jQWidgets Forums
jQuery UI Widgets › Forums › Plugins › Data Adapter › Optional data field's mapping
This topic contains 15 replies, has 5 voices, and was last updated by fjean 10 years, 6 months ago.
-
Author
-
Hello,
I encounter an error when I map an optional field from a child object.
Let’s take this example:var data = [{ "empName": "test", "age": "67", "department": { "id": "1234", "name": "Sales" }, "author": "ravi"}]; // prepare the data var source = { datatype: "json", datafields: [ { name: 'empName' }, { name: 'age' }, { name: 'id', map: 'department>id' }, { name: 'name', map: 'department>name' }, { name: 'author' } ], localdata: data }; var dataAdapter = new $.jqx.dataAdapter(source);
It assumes, if I am correct, that department will never be null.
In my code, I have:datafields : [ { name : 'id', type : 'number' }, { name : 'name', type : 'string' }, { name : 'parentId', map : 'parent>id', type : 'number' } ]
parent can be null so I have this error: TypeError: Cannot read property ‘id’ of null
I guess it should test parent before trying to retrieve id. If parent is null, then id is nullHi aigleborgne,
Thanks for writing.
Could you give a sample of your scenario? We cannot reproduce a problem with this version of jQWidgets.
var data = [{ “empName”: “test”, “age”: “67”, “department”: { “id”: “1234”, “name”: “Sales” }, “author”: “ravi” }, { “department”: { “id”: null, “name”: “Sales” }}, { “department”: null}];
// prepare the datavar source = { datatype: "json", datafields: [ { name: 'empName' }, { name: 'age' }, { name: 'id', map: 'department>id' }, { name: 'name', map: 'department>name' }, { name: 'author' } ], localdata: data }; var dataAdapter = new $.jqx.dataAdapter(source); dataAdapter.dataBind();
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHere is my code:
$scope.categories = [{"id":3,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Amazons","creatures":null,"children":null},{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},{"id":7,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Black bear","creatures":null,"children":null},{"id":8,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Brown bear","creatures":null,"children":null},{"id":10,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Cat","creatures":null,"children":null},{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},{"id":11,"parent":{"id":10,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Cat","creatures":null,"children":null},"name":"Jaguar","creatures":null,"children":null},{"id":12,"parent":{"id":4,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Mines","creatures":null,"children":null},"name":"Mercenary 1","creatures":null,"children":null},{"id":4,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Mines","creatures":null,"children":null},{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},{"id":9,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Polar bear","creatures":null,"children":null}]; var dataAdapter = new $.jqx.dataAdapter({ localdata : $scope.categories, datafields : [ { name : 'id', type : 'number' }, { name : 'name', type : 'string' }, { name : 'parentId', map : 'parent>id', type : 'number' } ], id : 'id', }, { autoBind: true }); var data = dataAdapter.getRecordsHierarchy('id', 'parentId', null, [ { name : 'name', map : 'label' } ]);
Purpose is to output a tree through jqTree.
autoBind is responsible for the error I mentionned.
I don’t really understand what it really do and documentation is not very clear on this subject. Since sources are minified, I can’t debug either.If I remove autoBind, I don’t get any error but my tree is empty for some reason.
Well, there might be some solution around, but it probably requires a good knowledge of data-adapter which I obviously don’t have.I invvestigated a bit and found out where is the problem.
Line 283 in jqx-data.js:var ag = ai.map.split(ae.mapChar); if (ag.length > 0) { var ak = al; for (var ah = 0; ah < ag.length; ah++) { ak = ak[ag[ah]]; } ao = ak } else { ao = al[ai.map] }
This doesn’t handle null parent object:
ak = ak[ag[ah]];
But even if I add a null test, it doesn’t produce any error but tree isn’t displayed either.if (ak[ag[ah]]) { ak = ak[ag[ah]]; }
I solved it. I debugged the entire bloc to understand what it does.
for (var ah = 0; ah < ag.length; ah++) { ak = ak[ag[ah]]; if (ak == null) { break; } }
So, it tries to reach property by progressing each step in sub-object (separating by mapChar, default ‘>’).
But without my test, it would throw an exception if any sub-object is null, because next step couldn’t be parsed.
This simple test will stop trying to get property if any sub-object is null.After this fix, my tree is correctly displayed and I think everything is good.
On a side note, mapChar doesn’t work but mapchar does.
Again, a camelcase problem and this time, documentation is wrong.Anyway to allow optional data fields without editing the minified jqwidgets sources?
Hi aigleborgne,
Editing of jQWidgets sources is prohibited by the EULA
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi,
It’s just an internal change until a fix is released. I don’t have much choice here : if I can’t use adapter right now, I will be forced to use another ui-library…
What are you suggesting then? What ETA could you give for a fix? Is there any other alternative?
Hi aigleborgne,
We don’t find a problem, so we do not have a work item about that.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comI am using the latest version so this problem should be reproduced easily.
As I said earlier, this following code doesn’t work with current version. Autobind will make it fail.$scope.categories = [{"id":3,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Amazons","creatures":null,"children":null},{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},{"id":7,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Black bear","creatures":null,"children":null},{"id":8,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Brown bear","creatures":null,"children":null},{"id":10,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Cat","creatures":null,"children":null},{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},{"id":11,"parent":{"id":10,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Cat","creatures":null,"children":null},"name":"Jaguar","creatures":null,"children":null},{"id":12,"parent":{"id":4,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Mines","creatures":null,"children":null},"name":"Mercenary 1","creatures":null,"children":null},{"id":4,"parent":{"id":1,"parent":null,"name":"Groups","creatures":null,"children":null},"name":"Mines","creatures":null,"children":null},{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},{"id":9,"parent":{"id":6,"parent":{"id":5,"parent":null,"name":"Monster","creatures":null,"children":null},"name":"Bear","creatures":null,"children":null},"name":"Polar bear","creatures":null,"children":null}]; var dataAdapter = new $.jqx.dataAdapter({ localdata : $scope.categories, datafields : [ { name : 'id', type : 'number' }, { name : 'name', type : 'string' }, { name : 'parentId', map : 'parent>id', type : 'number' } ], id : 'id', }, { autoBind: true }); var data = dataAdapter.getRecordsHierarchy('id', 'parentId', null, [ { name : 'name', map : 'label' } ]);
Hi aigleborgne,
Did you even try my working sample?
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi,
I have just tested your example and it works.
After comparing it with my code, I noticed the difference is datatype.You used json while I used arrays. In my understanding, I am providing an arrays of objects. Objects are provided using json format since it is returned by an ajax call. If I replace it with json, it works too.
But I don’t understand exactly how it is proceeded internally. arrays was certainly not a so bad option because everything works except sub-object reading when null.It might still be a problem with arrays or I have missed something about this datatype.
Maybe, you could add documentation about each datatype use cases.can confirm that optional data-fields don’t work in the “observablearray” datatype either
I’ve been trying to tackle the same situation with an “observablearray” Is there a workaround? I tried using knockout computed observables, but they don’t seem to work either.
-
AuthorPosts
You must be logged in to reply to this topic.