Skip to content

Instantly share code, notes, and snippets.

@taras
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taras/8725325 to your computer and use it in GitHub Desktop.
Save taras/8725325 to your computer and use it in GitHub Desktop.
Using promises to connect nested components

Consider a prompt where a user is asked to make a selection. A common solution is to treat the act of making a selection as an action and pass the value of the selection as an argument to the action. Actions bubble up to routes and up the route hierarchy. This method of handling user actions is inderect because the method that triggered the action isn't actually handing the result of that action.

I wanted to see how I could make this more direct and I thought using Promises would allow the actions to be async while maintaining control and readability.

Example use case: Autocomplete component uses dropdown component to show suggestions. Here is some pseudo code that shows how I thought this would work.

AutoCompleteComponent = Ember.Component.extend({
  actions: {
    // triggered when user entered some content
    submit: function() {
      var _this = this;
      this.dropdown.select().then(function(result){
        _this.send('action', result);
      }, function(reason){
        // nice to know that action was cancelled - but probably will not be used most of the time
      });
    }
  }
});

DropDownComponent = Ember.Component.extend({
  open: function() {
    
  },
  select: function() {
    var _this = this;
    return new Ember.RSVP.Promise(function(resolve, reject){
      _this.open();
      // need to wait until action is taken
      // I have no idea how to do that
      _this.close();
    });
  }
});

The problem is in DropDownComponent's select method. When the Promise is created, there is no obvious(to me) way to wait for an action to be triggered by the user - either Done or Cancel. Without that, there is no async event and the dropdown would just open and close without a selection.

promiseAction

AutoCompleteComponent = Ember.Component.extend({
  result: promiseAction(function(){
    return Em.$.ajax('/search?q=' + this.get('keyword'));
  });
});

auto-complete.hbs

{{input value=keyword}}
{{#action result}}
  {{drop-down content=result}}
{{else}}
  <!--
{{/action}}

drop-down.hbs

@taras
Copy link
Author

taras commented Feb 2, 2014

@machty pointed me to similar code that he's playing with https://gist.github.com/machty/b5114091dc4322bb4eca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment