zebzhao / Angular-QueryBuilder

A modernized Angular 4+ query builder based on jquery QueryBuilder
MIT License
297 stars 223 forks source link

addRule method error "Cannot read property '0' of undefined" for custom component fields #12

Closed rovico closed 6 years ago

rovico commented 6 years ago

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

When the first (or only) field in fields list is not default (external component) and I click "Add Rule" button, I see following exception in console.log (String numbers are wrong, because of wrong js map files in 0.2.0):


QueryBuilderComponent.html:10 ERROR TypeError: Cannot read property '0' of undefined
    at QueryBuilderComponent.addRule (query-builder.component.ts:240)
    at Object.eval [as handleEvent] (QueryBuilderComponent.html:10)
    at handleEvent (view.js:131)
    at callWithDebugContext (services.js:859)
    at Object.debugHandleEvent [as handleEvent] (services.js:434)
    at dispatchEvent (util.js:166)
    at element.js:225
    at HTMLButtonElement. (dom_renderer.js:66)
    at ZoneDelegate.497.ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (ng_zone.js:580)

It happens because addRule() method of QueryBuilderComponent is trying to get firs element of operatorMap[field.type]:

operator: this.operatorMap[field.type][0]

but this.operatorMap[field.type] is undefined.

I found two ways of workaround about this issue: I. The first is to set my own addRule() implementation in my config (config.addRule = (parent) => {...code...}), but in this case i cannot access to fields and operatorMap properties of QueryBuilderComponent and need to create my own; II. The second is to set operatorMap input like this: operatorMap = { combo: ['=', '<=', '>', '>=', '<'] } But in this case if the first field in fields list is not in this custom operatorMap, I'm getting the same issue; To avoid it i have to write all operators for each default field type.

Expected behavior

I. Check if field type exists in operatorMap and throw an error with clear description II. May be add "defaultOperator": this.operatorMap[field.type] ? this.operatorMap[field.type][0] : defaultOperator III. Make operatorMap extendable on component init (and not extend it when component is called recursive) IV. Add info about operatorMap for custom fields in documentation

Minimal reproduction of the problem with instructions

Just add custom (non-default) field as first in fields list.

What is the motivation / use case for changing the behavior?

Environment


Angular version: 5.2.1
TypeScript: 2.4.2


Browser:
- [x] Chrome (desktop) version 63.0.3239.108

Others:

P.S. : Javascrit map files in last release (0.2.0) are wrong and therefore it is very hard to debug...

zebzhao commented 6 years ago

Thank you for the detailed bug report, it really helps. I try to do all of the suggestions you listed and fix the source maps this week.

zebzhao commented 6 years ago

This issue should be fixed from version 0.2.2. Please reopen this issue if you are still having issues.