Reputation: 1065
I was hoping to get a value (an object store) calling my dojo module, but I keep getting undefined :
module:
define(['dojo/store/Memory', 'dojo/_base/xhr', "dojo/data/ObjectStore"],
function (Memory, xhr, ObjectStore) {
var oReachStore;
return {
Reaches: function (url) {
xhr.get({//get data from database
url: url,
//url: url,
handleAs: "json",
load: function (result) {
var ReachData = result.GetReachesResult;
var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
oReachStore = new ObjectStore({ objectStore: ReachStore });
},
error: function (err) { }
});
},
GetReaches: function () {
return oReachStore;
}
}
});
calls to module:
Data.Reaches(dataServiceUrl);//set the reach object store
ReachData = Data.GetReaches();//get the reach object store, but is always undefined
Upvotes: 1
Views: 313
Reputation: 1065
I needed to use a callback function for the function GetReach. The following modified code worked: Module:
define(['dojo/store/Memory', 'dojo/_base/xhr', "dojo/data/ObjectStore"],
function (Memory, xhr, ObjectStore) {
return {
GetReach: function (url, callback) {
xhr.get({//get data from database
url: url,
//url: url,
handleAs: "json",
load: function (result) {
var ReachData = result.GetReachesResult;
var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
var oReachStore = new ObjectStore({ objectStore: ReachStore });
callback(oReachStore);
},
error: function (err) { }
});
}
}
});
call from main page:
// ....
Data.GetReach(dataServiceUrl, SetReach);
function SetReach(data) {
//set data for the dropdown
ddReach.setStore(data);
}
Upvotes: 1
Reputation: 44685
Like you probably noticed by now (by reading your answer), is that you're using an asynchronous lookup (the XMLHttpRequest is asynchronous in this case), but you're relying on that store, before it might be set.
A possible solution is the use of promises/deferreds. I don't know which Dojo version you're using, but in Dojo < 1.8 you could use the dojo/_base/Deferred
module and since 1.8 you can use the dojo/Deferred
module. Syntax is slightly different, but the concept is the same.
First you change the oReachStore
to:
var oReachStore = new Deferred();
Then, inside your Reaches
function you don't replace the oReachStore
, but you use the Deferred::resolve()
function, for example:
return {
Reaches: function (url) {
xhr.get({//get data from database
url: url,
//url: url,
handleAs: "json",
load: function (result) {
var ReachData = result.GetReachesResult;
var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
oReachStore.resolve(ew ObjectStore({ objectStore: ReachStore })); // Notice the difference
},
error: function (err) { }
});
},
GetReaches: function () {
return oReachStore;
}
}
Then in your code you could use:
Data.Reaches(dataServiceUrl);//set the reach object store
Data.GetReaches().then(function(ReachData) {
console.log(ReachData); // No longer undefined
});
So now the ReachData
won't return undefined
, because you're waiting until it is resolved.
Deferreds are actually a common pattern in the JavaScript world and is in fact a more solid API compared to defining your own callbacks. For example, if you would get an error in your XHR request, you could use:
error: function(err) {
oReachStore.reject(err);
}
A simple example (I mocked the asynchronous request by using setTimeout()
) can be found on JSFiddle: http://jsfiddle.net/86x9n/
Upvotes: 1