Question

I have some promise-based code (MyLib) that I want to run on every model save so I extend the save function:

DS.Model.extend
  save: ->
    parentSave = @_super.bind this, arguments...
    deferred   = Ember.RSVP.defer()

    MyLib.func().then((val) =>
      @set 'prop', val

      parentSave()
        .then(deferred.resolve)
        .fail(deferred.reject)
    )

    DS.PromiseObject.create promise: deferred.promise

Note that the promise returned by MyLib.func() is an rsvp.js promise and not an Ember.RSVP promise.

This seems to work in practice but some of my tests are failing with You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run.

Even after I wrap the @set and parentSave calls with Ember.run, I still have async issues in my tests.

My question is: how do I extend the save function with async code in a way that also satisfies my tests?

Was it helpful?

Solution

Two things:

  1. The immediate error you're seeing is because all asynchronous code must run in Ember's run loop. That means that when your promise resolves and runs the deffered.resolve method, it must run that code inside of the run loop. So you have to do something like this:

    parentSave().then(() ->
        Em.run.next(() ->
            deferred.resolve()
        )
    )
    

    Hopefully that's right. Let me know if I'm missing something.

  2. As of Ember 1.5.0, you can't call _super in that manner. You must call it inline and not asynchronously.

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