This is a migrated thread and some comments may be shown as answers.

Kendo grid AngularJS and REST response

4 Answers 217 Views
Grid
This is a migrated thread and some comments may be shown as answers.
cyril
Top achievements
Rank 1
cyril asked on 07 Jul 2016, 09:39 PM

I have a  REST service that returns data. with Hal+json format. How do I consume the response in my Kendo Angular grid. My angular controller looks like this, but doesn't return anything:

...

vm.mainGridOptions = {

 dataSource: {
        transport: {
          read: {
            url: 'http://localhost:8080/people',
            dataType: 'jsonp'
          }
        },...

.

4 Answers, 1 is accepted

Sort by
0
cyril
Top achievements
Rank 1
answered on 08 Jul 2016, 03:43 PM

To be more specific: 

I have a Spring data rest service that returns data in 'hal+json'format:

 

{
  "_embedded" : {
    "people" : [ {
      "firstName" : "nes0",
      "lastName" : "Baggins2",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/people/1"
        },
        "person" : {
          "href" : "http://localhost:8080/people/1"
        }
      }
    }, {
      "firstName" : "nes0",
      "lastName" : "Baggins2",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/people/2"
        },
        "person" : {
          "href" : "http://localhost:8080/people/2"
        }
      }
    },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/people"
    },
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 14,
    "totalPages" : 1,
    "number" : 0
  }
}

 

I am using the Kendo AngularJS directives for my client:

 

function PeopleController(logger) {
  var vm = this;
  vm.title = 'People';
  logger.info('dataSource');
  vm.mainGridOptions = {
    dataSource: {
      type: 'application/hal+json;charset=UTF-8',
      transport: {
        read: {
          url: 'http://localhost:8080/people',
          dataType: 'jsonp' // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
        },
      },
      schema: {
        parse: function (response) {
          console.log("parse");
          console.log(JSON.stringify(response, null, 4));
          debugger;
          return response.people;
        }
      },
      // schema: {
      //   data: '_embedded.people'
      // },
      pageSize: 4,
      serverPaging: true,
      serverSorting: true,
      serverFiltering: true,
    },
    height: 550,
    width: '120px',
    filterable: {
      mode: 'row'
    },
    sortable: true,
    pageable: true,
    columns: [{
      field: 'lastName',
      title: 'Last Name',
      width: '120px',
      filterable: {
        cell: {
          operator: 'contains',
          showOperators: true
        }
      }
    }, {
        field: 'firstName',
        title: 'First Name',
        width: '220px',
        filterable: {
          cell: {
            operator: 'contains',
            showOperators: true
          }
        }
      }]
  };

 

The dataType is jsonp since I am running the client on port 3000 and the Rest service on local port 8080.
With this configuration, I have the dreaded error: Uncaught SyntaxError: Unexpected token :
the client issues this call:
http://localhost:8080/people?callback=jQuery22403825252088780162_1467989292513&take=4&skip=0&page=1&pageSize=4&_=1467989292514
and returns:

{
  "_embedded" : {
    "people" : [ ]
  },
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/people?page=0&size=20"
    },
    "prev" : {
      "href" : "http://localhost:8080/people?page=0&size=20"
    },
    "self" : {
      "href" : "http://localhost:8080/people"
    },
    "last" : {
      "href" : "http://localhost:8080/people?page=0&size=20"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/people"
    },
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 14,
    "totalPages" : 1,
    "number" : 1
  }
}

There is obviously no data returned and the parsing is wrong since it's a 'hal+json' format and I specified 'jsonp'.
So my question is:

What is the correct setup to read 'hal+json' response using Kendoui grid with Angular?

0
Boyan Dimitrov
Telerik team
answered on 11 Jul 2016, 01:48 PM

Hello cyril,

 

As you probably know, when remote requests are used, DataSource by default will use jQuery ajax to make those requests and expects json response. However it is possible to make the request without our Kendo UI DataSource built-in configuration, modify or extract the people data and pass it to the success callback of the transport.read operation. Please refer to the Local or Custom Transport CRUD Operations article for more information and sample code. 

 

Regards,
Boyan Dimitrov
Telerik by Progress
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
cyril
Top achievements
Rank 1
answered on 12 Jul 2016, 04:24 PM

I managed to get it working to a point. I solved the cross domain issue using the 'http-proxy-middleware' package in my gulp configuration.

function startBrowserSync(isDev, specRunner) {
..
 var proxyParticipant = proxyMiddleware('/people', { target: 'http://localhost:8080' });
 var options = {
    proxy: 'localhost:' + port,
    port: 3000,
    middleware: [proxyParticipant],
...

so I can drop the jsonp dataType and use json instead.

I have to format the URI generateded by the Kendo grid using  'parameterMap' so it matches what the Spring Data Rest server is expecting, for example:

http://localhost:3000/people?page=0&size=4&sort=firstName%2Casc

dataSource: {
        transport: {
          read: {
            url: '/people',
            dataType: 'json'
          },
          parameterMap: function (data, operation) {
            var output = null;
            switch (operation) {
              case 'read':
                var values = {};
                if (data.sort && data.sort.length > 0) {
                  var p = {};
                  if (!data.sort && data.sort.length < 0) {
                    p = data.page(1);
                  } else {
                    p = data.page
                  }
 
                  values["page"] = p - 1;
                  values["size"] = data.pageSize;
                  values["sort"] = data.sort[0]['field'] + ',' + data.sort[0]['dir'];
                  return values;
                }
 else {
                  values["page"] = data.page - 1;
                  values["size"] = data.pageSize;
                  return values;
}                

 

The grid will work with pagination and sort. I do however have an issue with the filters.

Spring Data Rest is expecting something along the line: 

http://localhost:8080/people/search/findByLastNameContains?name=John

 

The 'parameterMap' won't be helpful in that case. What would be the best practice in KendoUI to generate the previous URL? I don't see any easy way to reformat the url to insert'search', findByLastNameContains, etc...

Should I use the Local or Custom Transport CRUD Operations as you mentioned it? Is there any example how to handle the filters in that case?

Thanks.

 

0
Boyan Dimitrov
Telerik team
answered on 14 Jul 2016, 04:03 PM

Hello cyril,

My suggesiton in this case is to use the Custom CRUD operations and initiate a jQuery request to the provided url from the read function. As commented in the http://dojo.telerik.com/oTImU example e.data contains the information you need about the filtering to construct the proper url. 

Regards,
Boyan Dimitrov
Telerik by Progress
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
Tags
Grid
Asked by
cyril
Top achievements
Rank 1
Answers by
cyril
Top achievements
Rank 1
Boyan Dimitrov
Telerik team
Share this question
or