The simple demo JavaScript code below uses the RSVP.js Promise Library https://github.com/tildeio/rsvp.js/ to load some JSON data using AJAX and on completion fires off some code after all JSON data has loaded.
After that it runs a non ajax function in a chained then()
call
All my Promises are successful however it returns an error at the end as well!
I am not sure why the error is ran?
JSFiddle Demo : http://jsfiddle.net/jasondavis/fttzoggj/3/
var jsonPromiseCache = {};
// AJAX function to load JSON data using Promise()
var getJsonDataPromise = function(url, key) {
if (!jsonPromiseCache[key]) {
jsonPromiseCache[key] = new RSVP.Promise(function(resolve, reject){
// If jsonPromiseCached data is not set then make AJAX requiest to get it
var client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
console.log('---- "client" XMLHttpRequest/AJAX variable ======= ',client);
function handler() {
if (this.readyState === this.DONE) {
// On AJAX success, resolve() our Promise() and set result to cached variable
// to avoid duplicate AJAX requests for this jsonCache[key] Data where "key"
// is used to assign to each AJAX endpoint URL/request of JSON data...
// (milestones, tasks, users, etc...)
if (this.status === 200) {
jsonPromiseCache[key] = this.response;
console.log('---- jsonPromiseCache['+key+'] ====== ',jsonPromiseCache[key]);
// Resolve() the Promise() on AJAX success
resolve(this.response);
// On AJAX failure, reject() our Promise()
}else{
reject(this);
}
}
};
// If JSON data for this key is already jsonPromiseCached, then return the jsonPromiseCached version
// instead of making a new AJAX request!
});
}
return jsonPromiseCache[key];
};
New non-ajax promise
// testing a non ajax Promise
function initDomEvents() {
var eventsLoaded = true;
//if (eventsLoaded) {
jsonPromiseCache['domevents'] = eventsLoaded;
console.log('---- initDomEvents() ran');
// Resolve() the Promise()
//resolve(jsonPromiseCache['domevents']);
resolve();
// On false, reject() our Promise()
//}else{
// reject();
//}
};
EXAMPLE USAGE DEMO
// usage loading JSON data with AJAX using Promises
var promises = {
users: getJsonDataPromise('/echo/json/', 'users'),
task: getJsonDataPromise('/echo/json/', 'task')
};
RSVP.hash(promises)
.then(function(results) {
console.log('then() function ran on success of loading JSON data');
console.log(results);
console.log('results.users', results.users); // print the users JSON results
console.log('results.task', results.task); // print the task JSON results
})
.then(initDomEvents)
.finally(function(){
console.log('finally() function ran on success and failure.... It is always ran!');
})
.catch(function(reason){
console.log('[ERROR] REASON:',reason.statusText); //if any of the promises fails.
});
UPDATE
This new demo http://jsfiddle.net/jasondavis/fttzoggj/6/ adds a 3rd Promise and the 3rd one does not get ran! THe 2nd Promise function initDOmEvents()
returns this error now...
ERROR] REASON: ReferenceError: resolve is not defined
at initDomEvents (http://fiddle.jshell.net/_display/:91:9)
at G (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:6009)
at F (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:5928)
at L (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:6661)
at MutationObserver.h (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:1667)
New code added...
// testing a non ajax Promise
function initTaskModalLibraries() {
var taskModalScriptsLoaded = true;
if (taskModalScriptsLoaded) {
jsonPromiseCache['inittaskmodallibraries'] = taskModalScriptsLoaded;
console.log('---- initTaskModalLibraries() ran');
// Resolve() the Promise()
//resolve(jsonPromiseCache['domevents']);
resolve();
// On false, reject() our Promise()
}else{
reject();
}
};
RSVP.hash(promises)
.then(function(results) {
console.log('then() function ran on success of loading JSON data');
console.log(results);
console.log('results.users', results.users); // print the users JSON results
console.log('results.task', results.task); // print the task JSON results
})
.then(initDomEvents)
.then(initTaskModalLibraries)
.finally(function(){
console.log('finally() function ran on success and failure.... It is always ran!');
})
.catch(function(reason){
console.log('[ERROR] REASON:',reason); //if any of the promises fails.
});
UPDATE 2
I see now in my new non-ajax functions I am missing new RSVP.Promise(function(resolve, reject){})
Fixed demo http://jsfiddle.net/jasondavis/fttzoggj/8/
In your [ERROR] log line, remove .statusText
like so:
.catch(function(reason){
console.log('[ERROR] REASON:',reason); //if any of the promises fails.
});
you'll see this clickable error:
[ERROR] REASON:
ReferenceError: resolve is not defined initDomEvents()/_display/ (line 92)
G() rsvp.min.js (line 2)
F() rsvp.min.js (line 2)
L() rsvp.min.js (line 2)
h() rsvp.min.js (line 2)
Here's an updated fiddle that I think does what you intended. The main changes are:
return new RSVP.Promise(initDomEvents)
inside your first then
handler, which passes the returned result to the next then
(chaining),
and change the method signature of initDomEvents
:
function initDomEvents(resolve, reject) {
so that resolve/reject are defined.