ember.jsrsvp.jsrsvp-promise

How to chain a RSVP promise and return the original reject/success functions?


I have a simple rsvp helper that lets me wrap an ajax call as a simple promise

var PromiseMixin = Ember.Object.create({
    promise: function(url, type, hash) {
        return new Ember.RSVP.Promise(function(resolve, reject) {
            hash.success = function(json) {
                return Ember.run(null, resolve, json);
            };
            hash.error = function(json) {
                if (json && json.then) {
                    json.then = null;
                }
                return Ember.run(null, reject, json);
            };
            $.ajax(hash);
        });
    }
});

This works great and is then-able like you'd expect. The problem is when I have code that needs another promise that wraps this low level one first.

example

In my ember controller I might do this

        Appointment.remove(this.store, appointment).then(function() {
            router.transitionTo('appointments');
        }, function() {
            self.set('formErrors', 'The appointment could not be deleted');
        });

In my Appointment model I'm doing this for the "remove"

remove: function(store, appointment) {
    return this.xhr('/api/appointments/99/', 'DELETE').then(function() {
        store.remove(appointment);
        //but how I do return as a promise?
    }, function() {
        //and how can I return/bubble up the failure from the xhr I just sent over?
    });
},
xhr: function(url, type, hash) {
    hash = hash || {};
    hash.url = url;
    hash.type = type;
    hash.dataType = "json";
    return PromiseMixin.promise(url, type, hash);
}

Current my controller always falls into the "fail" state (even when my ajax method returns a 204 and is successful). How can I do a "chained promise" return from this remove method in my model to enable controllers to invoke it as a "thenable" like I have above?


Solution

  • Couldn't you do something like this?

    remove: function(store, appointment) {
        var self= this;
        return new Ember.RSVP.Promise(function(resolve,reject) {
            self.xhr('/api/appointments/99/', 'DELETE').then(function(arg) {
                store.remove(appointment);
                resolve(arg);
            }, function(err) {
                reject(err);
            });
        });
    },