We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Error when binding to Grid using DataManager

Currently I am having a problem with binding to the ejGrid control when using databinding with the DataManager control. Here is what my code looks like:

<script>
    var data =         var data = [
            {
                "id": "48084436-131a-4af8-8c66-13439d6901a9",
                "name": "T-Mobile"
            },
            {
                "id": "b24c920a-2794-45e1-ba8e-9dacf5b1422c",
                "name": "Tele2"
            },
            {
                "id": "eb36bf2b-24c6-464c-8348-b62d5adb5cc0",
                "name": "Ben"
            },
            {
                "id": "9047a03a-9aff-440a-a24d-c6daa45e26a6",
                "name": "Vodafone"
            },
            {
                "id": "b34b6baf-c047-4da7-9d89-e93f91321366",
                "name": "Telfort"
            },
            {
                "id": "8b49f3df-0f54-4116-9d92-f258c3841eaa",
                "name": "KPN"
            }
        ];

    $(document)
        .ready(
            function() {
                var datamanager = ej.DataManager({
                    url: 'api/Providers',
                    adaptor: new ej.WebApiAdaptor()
                });

                $("#gridProviders")
                    .ejGrid({
                        dataSource: datamanager,
                        allowSorting: true,
                        columns: [
                            { field: "id", headerText: "Provider ID" },
                            { field: "name", headerText: "Naam" }
                        ]
                    });
            });
</script>

<div class="main">
    <div id="gridProviders"></div>
</div>

When I switch the DataManager instance with the "data" variable (in memory array) the Grid works fine. When I try to use the datamanager I get the following javascript error:

Uncaught TypeError: Cannot read property 'length' of undefined(…) - ej.web.min.js (10) 

The API endpoint returns valid data, and while debugging the javascript I can see that the datamanager instance contains the data returned from the api. Just to be complete, here is the raw output of the api call (exactly the same as the in memory array, only not formatted):  

[{"id":"48084436-131a-4af8-8c66-13439d6901a9","name":"T-Mobile"},{"id":"b24c920a-2794-45e1-ba8e-9dacf5b1422c","name":"Tele2"},{"id":"eb36bf2b-24c6-464c-8348-b62d5adb5cc0","name":"Ben"},{"id":"9047a03a-9aff-440a-a24d-c6daa45e26a6","name":"Vodafone"},{"id":"b34b6baf-c047-4da7-9d89-e93f91321366","name":"Telfort"},{"id":"8b49f3df-0f54-4116-9d92-f258c3841eaa","name":"KPN"}]

Any information on what might causes this error would be greatly appreciated.

7 Replies

MV Maurits van Beusekom November 1, 2016 08:26 PM UTC

Note that I made a copy / paste mistake in the original post where I listed my code (double "var data =" on the second line). The correct version would be:

<script>
    var data = [
            {
                "id": "48084436-131a-4af8-8c66-13439d6901a9",
                "name": "T-Mobile"
            },
            {
                "id": "b24c920a-2794-45e1-ba8e-9dacf5b1422c",
                "name": "Tele2"
            },
            {
                "id": "eb36bf2b-24c6-464c-8348-b62d5adb5cc0",
                "name": "Ben"
            },
            {
                "id": "9047a03a-9aff-440a-a24d-c6daa45e26a6",
                "name": "Vodafone"
            },
            {
                "id": "b34b6baf-c047-4da7-9d89-e93f91321366",
                "name": "Telfort"
            },
            {
                "id": "8b49f3df-0f54-4116-9d92-f258c3841eaa",
                "name": "KPN"
            }
        ];

    $(document)
        .ready(
            function() {
                var datamanager = ej.DataManager({
                    url: 'api/Providers',
                    adaptor: new ej.WebApiAdaptor()
                });

                $("#gridProviders")
                    .ejGrid({
                        dataSource: datamanager,
                        allowSorting: true,
                        columns: [
                            { field: "id", headerText: "Provider ID" },
                            { field: "name", headerText: "Naam" }
                        ]
                    });
            });
</script>

<div class="main">
    <div id="gridProviders"></div>
</div>


FS Farveen Sulthana Thameeztheen Basha Syncfusion Team November 2, 2016 09:24 AM UTC

Hi Maurits, 
  
 
Thanks for your interest in Syncfusion products. 
  
 
We have analyzed your query and created sample based on your requirements but we are unable to reproduce this issue Cannot read property 'length' of undefined(…)”. Please refer the sample attached which can be downloaded from the below link. 
  
 
  
 
In your side, we suspect that  the issue may occur if you have return only data  at server-side WebAPIget method. While using WebAPI Adaptor, you have to return data in server-side as  objects “Items” and “Count”. 
  
 
Please refer the code snippet: 
  
public object Get() 
        { 
            List<OrdersView> ord = db.OrdersViews.ToList(); 
            . .  
  
            ord = ord.Skip(skip).Take(take).ToList(); 
            return new {Items = ord, Count = count };  
        }         
  
 
Please refer the below UG documentation  about how to bind the data using webAPI Adaptor. 
  
 
 
Please get back to us if you have any queries. 
  
 
Regards, 
  
Farveen.T 




MV Maurits van Beusekom November 2, 2016 02:19 PM UTC

Hi Favreen,

Ok I see what is going wrong. 

Is there a way to allow the Web API to stay the same (like not wrapping the results in an object like return new {Items = ord, Count = count };  ).  It is very difficult for me to change the Web API code (unless I create a proxy, which I rather not do).


MV Maurits van Beusekom November 2, 2016 04:33 PM UTC

Hi, 

I solved the problem on wrapping the results in an object "{ result: Object, count: number }", I have found a solution extending the WebApiAdaptor class and overriding the processResponse method:

var customWebApiAdaptor = new WebApiAdaptor().extends({
  processResponse: function(data, ds, query, xhr, request, changes) {
    if(data.constructor === Array)
      return { result: data, count: data.length };
    
    return super.processResponse(data, ds, query, xhr, request, changes);
  }
});

This will check if the data received as response is of type Array, if so it will wrap it in the desired object. If not it will just pass it to the super method for further processing. This works for me, however please let me know if there could be improvements.


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team November 3, 2016 01:25 PM UTC

Hi Maurits, 

When using WebApiAdaptor, it is recommended to return the object wrapped with the Items and Count pair from the server. Items hold the records for the current page whereas the Count holds the total records count.  Count is essential for functioning the pager in Grid and Grid to send POST requesting the records for the successive pages while performing pagination. Refer to the following Help Document. 


In your work around solution(custom adaptor), the Count has been calculated only for the current page which is not a correct procedure. Since it is mentioning the Count as current page’s record length, pager will not render the icons for navigation. Hence, we suggested to return the Items/Count pair from the server. 
  
If you would not like to perform the server-side actions for sorting/grouping/paging, you can populate all the records at the initial render of the Grid by setting the offline as true for the DataManager. In this case, you can simply return the records from the server as follows. 

        public object Get() 
        { 
              ..  
             .. .  
            return result; 
        } 
 
        $(function () { 
            var datamanager = ej.DataManager({ 
                url: 'api/Providers', 
                adaptor: new ej.WebApiAdaptor(), 
                offline: true 
            }); 
 
            $("#gridProviders") 
                .ejGrid({ 
                    dataSource: datamanager, 
                    allowSorting: true, 
                       ..  
                }); 
        }); 


However, if you would like to continue with the load on demand concept, you have to return the object as result/count pair. 

Regards, 
Seeni Sakthi Kumar S. 



MV Maurits van Beusekom November 3, 2016 03:28 PM UTC

Hi Seeni and Farveen,

Thank you both for the detailed explanations, the situation is clear to me now. I will start changing the backend system.

Kind regards, 

Maurits van Beusekom


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team November 4, 2016 04:17 AM UTC

Hi Maurits, 

Thanks for the update. If you require further assistance on this, please get back to us. 

Regards, 
Seeni Sakthi Kumar S. 


Loader.
Live Chat Icon For mobile
Up arrow icon