Question

I have a ember-data model with a relationship(many-many). So there is a computed property depends on the relationship element. I need to return boolean value based on data of the relationship property.

isAllowed: function(){
        return this.get('allowedUsers').then(function(data){
            var user = this.get('currentUser');
            return data.contains(user);
        }.bind(this));
}.property()

In the above code, isAllowed is the computed property and allowedUsers is in many relation with user model and async is set as true. isAllowed is getting set to the promise object rather returned boolean. I even tried to create another promise object like below but no luck.

 isAllowed: function(){
            return new Ember.RSVP.promise(function(resolve, reject){
               this.get('allowedUsers').then(function(data){
                var user = this.get('currentUser');
                 resolve(data.contains(user));
              }.bind(this));

            }.bind(this));
    }.property()

How can I make sure that isAllowed is set to boolean value rather the promise object?

Was it helpful?

Solution

You should use DS.PromiseObject:

isAllowed: Ember.computed('model.users.[]', 'session.currentUser', function() {
  return DS.PromiseObject.create({
    promise: this.get('session.currentUser').then((user) => {
      if (!user) {
        return false;
      }
      return this.get('model.users').isAny('id', user.get('id'));
    })
  });
})

http://emberjs.com/api/data/classes/DS.PromiseObject.html

OTHER TIPS

Try this:

isAllowed: function(key, value){
  if (arguments.length > 1) return value; // the setter was called

  this.get('allowedUsers').then(function(data){
    var user = this.get('currentUser');
    this.set("isAllowed", data.contains(user));
  }.bind(this));

  return false;
}.property()

If this were me, I would initialize with false, then set it to resolve in the setupController hook. For example, in your controller:

isAllowed: false, // Default with access denied

Now you can leverage your route. Routes are already juggling the model and controller, so that generally feels like the right place to resolve sideloading promises:

App.FooRoute = Ember.Route.extend({
  model: function () {
    //...
  },

  setupController: function (controller, model) {
    this.setUserAccess(controller, model);
    // more methods if needed...
  },

  setUserAccess (controller, model) {
    controller.get('allowedUsers').then(function(data){
      var user = controller.get('currentUser');
      controller.set("isAllowed", data.contains(user));
    });
  }
);

I wasn't sure where allowedUsers was coming from. You may need to tweak that.

You can do this either way, but I always feel a little icky when I override computed properties with a static property. Certainly nothing wrong with it, though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top