Question

I'm building a Dojo DataGrid from JSON data provided by my REST interface. The DataGrid loads the data fine using a QueryReadStore, but doesn't seem to work with the same same data piped into a JsonRestStore.

I'm using the following Dojo libs with Dojo 1.4.1:

dojo.require("dojox.data.JsonRestStore");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojox.data.QueryReadStore");
dojo.require("dojo.parser");

I declare my stores in the following manner:

var storeJRS = new dojox.data.JsonRestStore({target:"api/collaborations.php/1"});
var storeQRS = new dojox.data.QueryReadStore({url:"api/collaborations.php/1", requestMethod:"get"});

I create my grid layout like this:

var gridLayout = [
new dojox.grid.cells.RowIndex({ name: "Row #", width: 5, styles: "text-align: left;" }),
{
name: "Name",
field: "name",
styles: "text-align:right;",
width:20
},
{
name: "Description",
field: "description",
width:30
}
];

I create my DataGrid as follows:
<div dojoType="dojox.grid.DataGrid" jsid="grid2" store="storeQRS" structure="gridLayout" style="height:500px; width:1000px;"></div>

The above works, but if I use QueryReadStore as my store, the grid is created with the headers (Name, Description), but it isn't populated with any rows:
<div dojoType="dojox.grid.DataGrid" jsid="grid3" store="storeQRS" structure="gridLayout" style="height:500px; width:1000px;"></div>

Using FireBug, I can see that QueryReadStore is getting my JSON data from my REST interface. It looks like the following:

{"numRows":6,"items":[{"name":"My Super Cool Collab","description":"This is for all the super cool people in the super cool group","id":1},{"name":"My Other Super Cool","description":"This is for all the other super cool people","id":3},{"name":"This is another coll","description":"This is just some other collab","id":4},{"name":"some new collab","description":"this is a new collab","id":5},{"name":"yet another new coll","description":"uh huh","id":6},{"name":"asdf","description":"asdf","id":7}]}

Any ideas? Thanks.

Was it helpful?

Solution

To use the JsonRestStore your response would have to be only the items part of the sample you gave:

[{"name":"My Super Cool Collab","description":"This is for all the super cool people in the super cool group","id":1},{"name":"My Other Super Cool","description":"This is for all the other super cool people","id":3},{"name":"This is another coll","description":"This is just some other collab","id":4},{"name":"some new collab","description":"this is a new collab","id":5},{"name":"yet another new coll","description":"uh huh","id":6},{"name":"asdf","description":"asdf","id":7}]

Notice the array notation.

OTHER TIPS

The default service handler for JsonRestStore requests a range of items using a header and expects back an array of items requested, not an object. The code for handling requesting a range of items is:

if(args && (args.start >= 0 || args.count >= 0)){
    request.headers.Range = "items=" + (args.start || '0') + '-' + ((args.count && args.count != Infinity && (args.count + (args.start || 0) - 1)) || '');
}

If you want to, you can handle pagination yourself via query params by providing a custom getRequest OR overwriting the fetch function... but accepting an object instead of an array will be painful. Parsing such an object will require you to subclass the data store and provide a custom _processResults function:

dojo.declare("dojox.data.CustomStore", dojox.data.JsonRestStore, {
    _processResults: function(results, deferred){
        var items = SOME_MAPPING_FUNCTION_HERE(results);
        var count = COUNT_RESULTS_HERE;
        return {totalCount:deferred.fullLength || (deferred.request.count == count ? (deferred.request.start || 0) + count * 2 : count), items: items};
    }
}

That only handles parsing the response... I'm not sure it's possible to alter the posted content that easily.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top