ember-concurrency icon indicating copy to clipboard operation
ember-concurrency copied to clipboard

Make it possible to use task infrastructure to loop over observables

Open machty opened this issue 9 years ago • 7 comments
trafficstars

machty avatar Feb 20 '16 17:02 machty

Not sure if you mean what I think you mean, but I really needed this feature and ember-cpm's computedPromise just wasn't cutting it (due to an infinite loop bug and a state sharing bug).

Here's what I did:

computedTask = (depKeys..., fn) ->
  computed (key) ->
    unless @[key + "Task"]?
      @[key + "Task"] = task =>
        @[key + "TaskCurrentResult"] = yield fn.call @
        @notifyPropertyChange key
      .restartable()
      for depKey in depKeys
        @addObserver depKey, @, -> 
          @get(key + "Task").perform()
      @get(key + "Task").perform()
    @[key + "TaskCurrentResult"]

Then, I use this like so:

DS.Model.extend
  comments: hasMany "comment", async: true
  isApproved: computedTask "comments.lastObject", ->
    @get "comments"
    .then (comments) ->
      comments.get("lastObject")
    .then (comment) ->
      comment.get("message") is "lgtm"

But yeah, it'd be great if ember-concurrency could have observable computed property feature. Also, if my implementation isn't too much cancer, I can do a pr if no one else is working on this already.

foxnewsnetwork avatar Mar 02 '16 18:03 foxnewsnetwork

@foxnewsnetwork I was actually referring to RxJS Observables, of which I have (an unpublished) spike here: http://ember-concurrency.com/#/docs/examples/observables

I'm not sure I totally follow but are you saying you want a task to be performed when some observed property changes?

machty avatar Mar 02 '16 19:03 machty

Yes, exactly that. The Task api already has an on method to listen to events, but I wound up needing an observes method to handle a lot of the ember-data async logic.

But lol, I guess that's another feature for another day.

foxnewsnetwork avatar Mar 02 '16 19:03 foxnewsnetwork

@foxnewsnetwork yeah, I'm not ready to add that feature just yet until we've all had time to absorb the current API. There might just be another task-friendly approach to what you're trying to do that avoids the ugliness of observers.

machty avatar Mar 02 '16 19:03 machty

@machty I'd love to see the observable integration in. Our ember app needs to poll our backend and an Observable would be perfect for this. We're also aiming to get a release of orbit.js out soon which uses Observables for realtime queries(rxjs under the hood), would be awesome if those could be unsubscribed automatically in components.

opsb avatar Mar 21 '16 10:03 opsb

I have a similar need. I often use this pattern:

  myPromiseComputedProperty: computed('a', 'b', function() {
    const _this = this;
    let prom = new Ember.RSVP.Promise(function(resolve, reject) {
      let myVar = null; 
      myVar = _this.get('myTask').perform();
      if(!myVar) {
        reject("error");
      } else {
        resolve(myVar);
      }
    });
    return DS.PromiseObject.create({ promise: prom });
  }),

  myTask: task(function * () {
     ...
  })

It does not work with an Ember-Concurrency task. Maybe I have the wrong approach/antipattern. Happy to hear your take on it.

20v100 avatar Oct 29 '16 11:10 20v100

@20v100 you shouldn't need to wrap in a promise

let prom = this.get('myTask').perform();
return DS.PromiseObject.create({ promise: prom });

jasimon avatar Mar 17 '17 01:03 jasimon