Promises and computed properties

Another way to handle this kind of situation is to encapsulate the promise resolution inside the computed property:

myThing: function(k,v) {
  if (arguments.length > 1) {
    return v;
  }
  var self = this;
  computeSomeValue().then(function(theValue) {
    self.set('myThing', theValue);
  });
}).property()
```

That handles the simpler cases. If you want it to be really bulletproof against multiple invalidations while the promise is still resolving, you'll want to track a little more. The following is some coffeescript I've been using for this:

````coffeescript
promised = (initialValue, func) ->
  flightKey = '_promisedInFlight' + Ember.guidFor({})
  (k,v) ->
    return v if arguments.length > 1
    this[flightKey] ?= 0
    this[flightKey] += 1
    myNumber = this[flightKey]
    func.apply(this, [k,v]).then((result) =>
      if this[flightKey] <= myNumber
        @set(k, result)
      this[flightKey] -= 1
    )
    initialValue
```

You can use it like this:

```
myThing: promised('loading...', function(k,v){ return somePromise() })
```

This `initialValue` lets you pick what the value of the computed property should be while the promise is still unresolved.
11 Likes