Login Register

Fetching Multiple Items and Values

For this example, we'll assume the simple data source detailed on the previous page

Working with Multiple Items

You will likely want to access multiple items from such a data source as in the preceding example. No problem! Dojo.data Read API provides a mechanism for loading a set of items. All you have to do is provide the following information to the fetch function of the Read API:

  • This is what I want (if I don't tell you something, get everything)
  • Do this if there is an error
  • Do that when everything is loaded

If this sounds like it might be event-driven, that's because it is. The prime method to call, dojo.data.api.Read.fetch(), is asynchronous. This is because, in a wide variety of data access cases, the datastore will have to make a request to a server service to get the data. Many I/O methods for doing server requests only behave in an asynchronous manner. Therefore, the primary search function of dojo.data is asynchronous by definition.

In this example, the Read API is used with the following values:

fetch()
Asynchronous API that fetches a set of items which match a list of attributes.
getValue()
Takes an item and an attribute and returns the associated value.

The following code fragment returns all items:

var pantryStore = new dojo.data.ItemFileReadStore({ url: "pantry_items.json" });
//Define a callback that fires when all the items are returned.
var gotList = function(items, request){
    var itemsList = "";
    dojo.forEach(items, function(i){
       itemsList += pantryStore.getValue(i, "name") + " ";
    });
    console.debug("All items are: " + itemsList);
}
var gotError = function(error, request){
    alert("The request to the store failed. " +  error);
}
//Invoke the search
pantryStore.fetch({
    onComplete: gotList,
    onError: gotError
});

Working with Lots of Items

Now that we've looked at dealing with getting a list of items in one batch, what if the list is huge? It could take a long time to get all the items, push them into an array, and then call the callback with the array of items. Wouldn't it be nice if you could stream the items in, one at a time, and do something each time a new item is available? Well, with dojo.data, you can do that! There is an alternate callback you can pass to fetch() that is called on an item by item basis. It is the onItem callback.

In the following example, the code will request that all items be returned (an empty query). As each item gets returned, it will add a textnode to the document. In this example, the Read API is used with the following values:

fetch()
Asynchronous API that fetches a set of items which match a list of attributes.
getValue()
Takes an item and an attribute and returns the associated value.

The following code fragment loads all items and streams them back into the page:

var pantryStore = new dojo.data.ItemFileReadStore({url: "pantry_items.json" } );
var body = dojo.body(); // node to put output in
// Define the onComplete callback to write
// COMPLETED to the page when the fetch has
// finished returning items.
var done = function(items, request){
    body.appendChild(document.createTextNode("COMPLETED"));
}
//Define the callback that appends a textnode into the document each time an item is returned.
gotItem = function(item, request){
    body.appendChild(
        document.createTextNode(
            pantryStore.getValue(item, "name")
        )
    );
    body.appendChild(document.createElement("br"));
}
//Define a simple error handler.
var gotError = function(error, request){
    console.debug("The request to the store failed. " +  error);
}
//Invoke the search
pantryStore.fetch({
    onComplete: done,
    onItem: gotItem,
    onError: gotError
});

Note: If the onItem callback is present in the parameters to fetch, then the first parameter to the onComplete callback, the items array, will always be null. Therefore, onItem is streaming only mode and does not rely on onComplete for anything other than a signal that the streaming has ended.

dojo.data.JsonItemStore

Does dojo.data.JsonItemStore, require a "fixed" format?  When I access JSON data that starts with


{"identifier":"deptcode",
  "items":[


my program works OK.  When I use a different format such as:


{"ResultSet":{
  "ResultSetLength":45,
  "Result":[


I get this error: "'length' is null or not an object".


Do I need to overrride some Method, such as fetch?


 

document.appendChild ?

FireFox 2.0 seemed to work with document.body.appendChild instead.