Using this.sendAction() in components?

11,958

Solution 1

When you are using this.sendAction('actionName') you're bubbling up an action which you'll have to catch on the component/controller with actions

//controller/route/component.js
actions: {
  actionName: function() {
    //Do something
  }
}

If you want to send that up the chain, you'll have to call sendAction('') again on the component/controller and catch it again on the parent (and so on).

The other approach this.get('action')() uses closure actions, which are regular javascript functions. These are the preferred way to invoke actions in Ember 1.13.X as far as I know. One neat thing that closure actions have is that you can have return values. Meaning that you can have something like this:

//a controller
actions: {
  saveResult() {
    return this.get('model').save(); //notice the return (which returns a promise)
  }
}

//some template that uses the controller above
{{a-component save=(action 'saveResult')}} // Passes the saveResult action to the component

//a-component.js
actions: {
  someAction: function() {
     this.attrs.save().then(() => {
       //Do something with the return value
     });
  }
}

A lot can be written about closure actions, but others have written far better than I could, so I recommend the following articles:

And if you're new to the whole DDAU (Data Down Actions Up) concept, I really recommend Sam's article about the concept in general.

Update: There's also an addon (linked in the comments by @locks) which allows closure actions to bubble to routes. Note that if you look to upgrade Ember to more recent versions (3.8 and up), route-actions will not be compatible.

Solution 2

For those using Ember version >=3.4:

Use closure actions instead of sendAction

sendAction has been deprecated in 3.4. You can find an example of how to define closure actions under the relevant deprecation text:

https://deprecations.emberjs.com/v3.x/#toc_ember-component-send-action

Share:
11,958
maximusmusterus
Author by

maximusmusterus

Updated on June 20, 2022

Comments

  • maximusmusterus
    maximusmusterus almost 2 years

    I am using Ember 2.2.0

    When writing components I used to propagate events from the component to the route (or whatever embeds the component) with this.sendAction(…). I checked out the docs lately and discovered that they advise another approach. https://guides.emberjs.com/v2.2.0/components/triggering-changes-with-actions/

    this.get('action')();
    

    Since Ember is known to be very opinionated I want to stick as much to the best practices as possible. But I am not sure if the docs might be out of date or the tutorials using sendActions are.

    So I would like what is the way to do this?