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.

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
  • Optional data field's mapping #51062

    aigleborgne
    Participant

    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 null

    Optional data field's mapping #51067

    Peter Stoev
    Keymaster

    Hi 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 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);
                dataAdapter.dataBind();
    

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    Optional data field's mapping #51071

    aigleborgne
    Participant

    Here 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.

    Optional data field's mapping #51079

    aigleborgne
    Participant

    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]];
    }
    Optional data field's mapping #51080

    aigleborgne
    Participant

    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.

    Optional data field's mapping #51081

    aigleborgne
    Participant

    On a side note, mapChar doesn’t work but mapchar does.
    Again, a camelcase problem and this time, documentation is wrong.

    Optional data field's mapping #51094

    orzarchi
    Participant

    Anyway to allow optional data fields without editing the minified jqwidgets sources?

    Optional data field's mapping #51124

    Peter Stoev
    Keymaster

    Hi aigleborgne,

    Editing of jQWidgets sources is prohibited by the EULA

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    Optional data field's mapping #51154

    aigleborgne
    Participant

    Hi,

    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?

    Optional data field's mapping #51159

    Peter Stoev
    Keymaster

    Hi aigleborgne,

    We don’t find a problem, so we do not have a work item about that.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    Optional data field's mapping #51167

    aigleborgne
    Participant

    I 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'
    		} ]);
    Optional data field's mapping #51169

    Peter Stoev
    Keymaster

    Hi aigleborgne,

    Did you even try my working sample?

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    Optional data field's mapping #51182

    aigleborgne
    Participant

    Hi,

    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.

    Optional data field's mapping #51646

    orzarchi
    Participant

    can confirm that optional data-fields don’t work in the “observablearray” datatype either

    Optional data field's mapping #52148

    banksjh
    Participant

    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.

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic.