- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
Fetching Multiple Items and Values
Submitted by dante on Fri, 05/11/2007 - 01:04.
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
});
//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
});
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.
- Printer-friendly version
- Login or register to post comments
- Subscribe post
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.