0

I'm wrapping a simple jQuery promise with RSVP and noticed that when I cause an error on purpose the failure callback is never invoked. I assume it's because when you use vanilla jQuery and the callback throws an error, the returned promise will not be moved to failed state (the opposite of the spec).

If I need to use jQuery $.ajax but I want to get true resolve/reject callbacks with RSVP what (if anything) can I do to the example below?

var peoplePromise = new Ember.RSVP.Promise(function(resolve, reject) { 
    $.getJSON('/api/people/', resolve).fail(reject).error(reject);     
});                                                                    

var catPromise = new Ember.RSVP.Promise(function(resolve, reject) {    
    $.getJSON('/api/cats/', resolve).fail(reject).error(reject);       
});                                                                    

Ember.RSVP.all([peoplePromise, catPromise]).then(function(things) {    
    things[0].forEach(function(hash) {                                 
        var thing = App.Person.create(hash);                           
        Ember.run(self.people, self.people.pushObject, thing);         
    });                                                                
    things[1].forEach(function(hash) {                                 
        var wat = hash.toJSON(); //this blows up                                      
        var thing = App.Person.create(hash);                           
        Ember.run(self.people, self.people.pushObject, thing);         
    });                                                                
}, function(value) {                                                   
    alert(value.status + ": promise failed " + value.responseText);    
});
Toran Billups
  • 27,111
  • 40
  • 155
  • 268

1 Answers1

2

Example here: http://www.youtube.com/watch?feature=player_detailpage&v=g5CSaK3HqVA#t=1080

var ajaxPromise = function(url, options){
  return Ember.RSVP.Promise(function(resolve, reject) {

    var options = options || {};

    options.success = function(data){
      resolve(data);
    };

    options.error = function(jqXHR, status, error){
      reject([jqXHR, status, error]);
    };

    $.ajax(url, options);
  });
};

var peoplePromise = ajaxPromise('/api/people/',{
  dataType: "json"
});

var catPromise = ajaxPromise('/api/cats/',{
  dataType: "json"
});

Ember.RSVP.all([peoplePromise, catPromise]).then(function(things) {
  things[0].forEach(function(hash) {
    var thing = App.Person.create(hash);
    Ember.run(self.people, self.people.pushObject, thing);
  });
  things[1].forEach(function(hash) {
    var wat = hash.toJSON(); //this blows up
    var thing = App.Person.create(hash);
    Ember.run(self.people, self.people.pushObject, thing);
  });
}, function(args) {
  var jqXHR = args[0];
  alert(jqXHR.status + ": promise failed " + jqXHR.responseText);
});

http://emberjs.jsbin.com/aREDaJa/1/

Michael Benin
  • 4,317
  • 2
  • 23
  • 15
  • For correct transition to Error route in Ember one needs to replace `reject(arguments)` by `reject(new Error('your_message'))`. – boxdot Jul 31 '14 at 13:36
  • Finite, I modified my answer. Will passing the error from options.error be sufficient, I feel adding a default error message is cryptic. – Michael Benin Aug 18 '14 at 16:44
  • @finite after using this, I found passing in all 3 to be the most useful. Updated. – Michael Benin Feb 05 '15 at 21:55