Search code examples
ember.jsrsvp.js

Catching a Promise exception and returning a default value


I am having an issue where I want to return a default value if an exception occurs on a promise. The array I return does not seem to work properly.

My Route model hook

model: function() {
    return {
        menuItems : this.store.find('menuItem').catch(function(error) {
            Ember.Logger.error('Retrieving Menu Items', error);
            return [];
        }),

My controller mode

selectFirstMenuItem: function() {
    var model = this.get('model');

    //At this point model.menuItems is some weird object 
    //with an _id : 26, _label : undefined, _result: Array(0), _state : 1 etc. 
    //(maybe a Promise?),  the .get method throws an undefined exception.
    if(model.menuItems.get('length') > 0 ) {
        ...
    }
}.observes('model.menuItems.@each'),

Solution

  • You can make this work by returning an Ember.RSVP.hash instead of a regular object containing a promise as follows:

    App.IndexRoute = Ember.Route.extend({
      model: function() {    
        return Ember.RSVP.hash({
          menuItems: this.store.find('menuItem').then(
            function(menuItems){ return menuItems; },
            function(error) {
              Ember.Logger.error('Retrieving Menu Items', error);
              return [];
            })
        });
      }
    });
    

    And then watching for the length property of menuItems as follows:

    App.IndexController = Ember.ObjectController.extend({
      menuItemsObserver: function() {
        var menuItems = this.get('model.menuItems');
    
        var nonZeroLength = Ember.get(menuItems, 'length');
        if(nonZeroLength ) {
          console.log("The length is NOT zero");
        }
        else {
          console.log("The length is zero");
        }
      }.observes('model.menuItems.length')  
    });
    

    Working example here