tarponjargon
tarponjargon

Reputation: 1032

ember: promise for a controller action that calls a service method

I have an action on my controller that calls a service method. The service method is an ember-data query. I need to return a message contained in that ember-data payload back to the controller (print it to the screen).

I am having a hard time figuring out how to get the controller action (function) to "wait" for the service method to finish.

The controller action:

// controller action
processCoupon() {
    // the service method I want to wait for the response for
    let messageObject = DS.PromiseObject.create({
        promise: this.get('cart').processCoupon()
    });

    // the message
    messageObject.then(response => {
        let promo_message = messageObject.get('promo_message');
        if (promo_message.message && promo_message.alert) {
            if (!promo_message.success) {
                // show error message in alert with ember-cli-notifcations
            } else {
                // show success message in alert with ember-cli-notifcations
            }
        }
    });
},

Method in the service I want to wait for the response for:

// service method syncs cart info (containing promo) with the backend
// promo_message is in the response payload
processCoupon() {
    return this.get('store').findRecord('cart', get(this, 'cartObj.id')).then(cart => {
        cart.save().then(newCart => {
            set(this, 'cartObj', newCart); // sets response to property on service
            return newCart.get('promo_message');
        });
    });
},

the 'response' in the promise is empty, and the MessageObject itself has no content. So I'm doing something wrong here (and it's likely misunderstanding promises).

I messed around with RSVP promises and didn't do well there either. What am I missing, OR is there a better way to do this?

Upvotes: 0

Views: 457

Answers (2)

Gennady Dogaev
Gennady Dogaev

Reputation: 5991

Your service method should return a promise. Then you can use it like this: this.get('cart').process().then((response) => {/*your code working with service's response*/});

You also should be aware that if you use ember data, it will return a model instance, not an original response from your back-end.

And, in order to return promise, you need to wrap your service's method in new Promise((resolve, reject) => {/*asynchronous code here*/});

Upvotes: 1

renno
renno

Reputation: 2827

I've done something similar with Ember.RSVP.Promise() is that what you want?

// controller
myMessage = null,
actions:
cartCoupon() {
  let msg = this.get('cart').processCoupon();
  msg.then(myDataMessage => this.set('myMessage', myDataMessage);
}


//service
processCoupon() {
  return new Ember.RSVP.Promise( resolve => {
    let data = this.get('store').findRecord('cart', get(this, 'cartObj.id')).then(cart => {
        cart.save().then(newCart => {
            set(this, 'cartObj', newCart); // sets response to property on service
            return newCart.get('promo_message');
        });
    });
    resolve(data);
  });
}

Upvotes: 1

Related Questions