columns and data using well-formed objects

columns and data using well-formed objects

dykstraddykstrad Posts: 20Questions: 0Answers: 1
edited May 2014 in Free community support

I ran into an issue where I was trying to pass dataTables an array of well formed objects in columns. After looking into it a bit further I found out that _fnCamelToHungarian was erroring because it was finding the prototype methods in the _hungarianMap and trying to get the charAt(0). I solved this problem by changing the method to only look at enumerable types using Object.keys(user).

function _fnCamelToHungarian ( src, user, force )
    {
        if ( ! src._hungarianMap ) {
            _fnHungarianMap( src );
        }
    
        var hungarianKey;

        /** MODIFIED **/
//      $.each(user, function (key, val) {
//          hungarianKey = src._hungarianMap[ key ];
        $.each(Object.keys(user), function (key, val) {
            hungarianKey = src._hungarianMap[ val ];
        /** MODIFIED **/
    
            if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
            {
                // For objects, we need to buzz down into the object to copy parameters
                if ( hungarianKey.charAt(0) === 'o' )
                {
                    // Copy the camelCase options over to the hungarian
                    if ( ! user[ hungarianKey ] ) {
                        user[ hungarianKey ] = {};
                    }

                    /** MODIFIED **/
//                  $.extend( true, user[hungarianKey], user[key] );
                    $.extend( true, user[hungarianKey], user[val] );
                    /** MODIFIED **/
    
                    _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
                }
                else {
                    /** MODIFIED **/
//                  user[hungarianKey] = user[ key ];
                    user[hungarianKey] = user[ val ];
                    /** MODIFIED **/
                }
            }
        } );
    }

Following this I ran into a similar problem passing well-formed data objects into fnAddData. I solved this by changing the is plain object check to instanceof Object.

this.fnAddData = function( data, redraw )
        {
            var api = this.api( true );
        
            /* Check if we want to add multiple rows or not */
            /** MODIFIED **/
//            var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
//              api.rows.add( data ) :
//              api.row.add( data );
            var rows = $.isArray(data) && ( $.isArray(data[0]) || data[0] instanceof Object/*|| $.isPlainObject(data[0])*/ ) ?
                api.rows.add( data ) :
                api.row.add( data );
            /** MODIFIED **/

            if ( redraw === undefined || redraw ) {
                api.draw();
            }
        
            return rows.flatten().toArray();
        };

I would be interested in anyone's thoughts on this solution and if there are any parts that I have missed.

Replies

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Can you link me to an example that shows this problem please? I'd like to get this fixed in the core if I can reproduce the error.

    Regarding fnAddData - I'd suggest using the new API. rows.add() and row.add() doesn't suffer the ambiguity of fnAddData with regard to checking if one row or multiple are being added.

    Thanks,
    Allan

  • dykstraddykstrad Posts: 20Questions: 0Answers: 1

    Good idea with rows.add(), because the isPlainObject returns false on a instance, it was calling row.add.

    I am currently working on a test case for you to see, unfortunately I don't have a basic link to give you at this time as my application is in it's testing phase.

  • dykstraddykstrad Posts: 20Questions: 0Answers: 1
    edited May 2014

    Here is the fiddle showing the problem loading and array of instances into fnAddData.
    http://jsfiddle.net/96UpW/1/

    However the best solution there is just to switch to the new API

  • dykstraddykstrad Posts: 20Questions: 0Answers: 1
    edited May 2014

    Here is the jsFiddle showing the issue with passing an array of instances into columns.
    http://jsfiddle.net/96UpW/4/

    The fiddle doesn't show the practicality of this but I shall explain. We use ESRI to get Field objects, and each column in our DataTable is a field object. Unfortunately ESRI overloads some of the prototype functions (constructor etc...) for that instance. So when we load a array of Field objects into columns it errors when doing the CamelToHungarian mapping. My solution to this problem is above.

    Hope this helps.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Thanks for the links. The columns objects should be just plain objects - I haven't put anything in to allow them to be instances, and the $.extend() that is used for the columns will likely fall over when working with instances.

    Allan

  • dykstraddykstrad Posts: 20Questions: 0Answers: 1

    You are correct that $.extend() will convert the instance type to whatever the target is, in this case a plain object. However it would probably still be a good idea for the _fnCamelToHungarian function to ensure it is dealing with enumerable properties (Object.keys etc...) or at least give some sort of useful error if the data is not right.

    Thank you for your time Allan.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Yup - that's a good point. I think there is a related issue somewhere (don't have a link at the moment, its in my todo list for the next release!). I'll have a look at improving this. Thanks for the feedback!

    Allan

This discussion has been closed.