# sendAction as a promise

**URL:** <https://discuss.emberjs.com/t/sendaction-as-a-promise/3143>\
**Category:** Design\
**Created:** [October 28, 2013, 10:17am UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143 "2013-10-28T10:17:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![seif](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@seif](https://discuss.emberjs.com/u/seif)\
**Post date:** [October 28, 2013, 10:17am UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/1 "2013-10-28T10:17:17Z")

</div>

I’m working on a toggle button component, that needs to know if the action was completed or not, so it can `@set 'isSending', false`.

Easy way, is to just reveal the binding outside, and whoever handles the action handles setting `isSending` to false.

```auto
{{toggle-btn
    text="Like"
    selectedText="Liked"
    icon="fa fa-heart"
    toggleState=post.isVoted
    isSending=isVoting
    action="vote"
    param=post
}}

```

But it doesn’t make sense to be handled in the action, because it is related to the component.

So i was thinking maybe promises can solve this problem. Maybe something like this

```auto
new Ember.RSVP.Promise( ->
  self.sendAction('action', self.get('param'))
).then ->
  console.log 'done'

```

Any idea if this is possible, or does it require ember support?

---

<div class="post-metadata">

**Author:** ![bantic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/bantic/32/4631_2.png) [@bantic](https://discuss.emberjs.com/u/bantic)\
**Post date:** [October 28, 2013, 3:53pm UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/2 "2013-10-28T15:53:36Z")

</div>

Hey @seif, the short answer is that this doesn’t work this way in Ember. As I understand it, Ember’s action handlers only ever return true or false, and these boolean return values are used to determine whether handling the action “bubbles” to the next target up the chain. Even though actions sent from a component using `sendAction` do not bubble, they use the same action-handling code that the rest of ember uses, which coerces the return value to true or false.

Ember’s [implementation of `sendAction`](https://github.com/emberjs/ember.js/blob/7db41bc490e2d492608d4744ae2a5eeac7cd4fed/packages/ember-views/lib/views/component.js#L212-L215) internally uses [`triggerAction`](http://emberjs.com/api/classes/Ember.TargetActionSupport.html#method_triggerAction). `sendAction` doesn’t actually return the result of `triggerAction`, but even if it did it would only be a boolean, as `triggerAction` only returns booleans.

I think the best way to do what you want to do here is to bind a property in the component to a property in its controlling context that changes asynchronously. If you needed to do some cleanup inside the component you could add an observer to that property, too.

---

<div class="post-metadata">

**Author:** ![bantic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/bantic/32/4631_2.png) [@bantic](https://discuss.emberjs.com/u/bantic)\
**Post date:** [October 28, 2013, 3:59pm UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/3 "2013-10-28T15:59:10Z")

</div>

Here’s a jsbin showing how you might do this by observing a property on your controller:

[http://jsbin.com/AJeqEki/3/edit](http://jsbin.com/AJeqEki/3/edit)

---

<div class="post-metadata">

**Author:** ![seif](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@seif](https://discuss.emberjs.com/u/seif)\
**Post date:** [October 29, 2013, 7:47am UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/4 "2013-10-29T07:47:07Z")

</div>

So I still have to set `isSending` from outside of the component. I guess there is no other way around it

---

<div class="post-metadata">

**Author:** ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)\
**Post date:** [February 18, 2014, 1:38pm UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/5 "2014-02-18T13:38:22Z")

</div>

@seif I’ve been thinking about something very similar lately. I spoke to @machty about it and he pointed me to a computed property that he’s been using.

```javascript
// A PromiseAction is an action set on the controller,
// but not in the actions hash, which allows it to be
// passed in directly to the component. The component
// just sees it as a function that it can call that
// returns a promise. This is nice for when the component
// needs to emit some action that can fail; if it fails
// it can clean up after itself.
 
// Example:
// export default Controller.extend({
// setSomeValueAsyncly: promiseAction(function(newValue) {
// this.set('something', newValue);
// // simulate a slow set...
// return new Ember.RSVP.Promise(function(resolve) {
// Ember.run.later(resolve, 1000);
// });
// })
// });
//
// {{some-component on-change=setSomeValueAsyncly}}
 
export default function promiseActionComputedProperty(fn) {
  return Ember.computed(function() {
    var self = this;
    return function() {
      var args = arguments;
      return new Ember.RSVP.Promise(function(resolve) {
        resolve(fn.apply(self, args));
      });
    };
  });
};

```

I’m looking at how I can use it myself but I just wanted to share.

---

<div class="post-metadata">

**Author:** ![seif](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@seif](https://discuss.emberjs.com/u/seif)\
**Post date:** [February 18, 2014, 7:13pm UTC](https://discuss.emberjs.com/t/sendaction-as-a-promise/3143/6 "2014-02-18T19:13:11Z")

</div>

@tarasm That is awesome, thanks a lot for sharing 😄
