Cancelling async association promises when Model is deleted


#1

Hi everyone!

So, I’ve hit what I think is a weird issue and I wanted to ask a couple questions around it.

Basically, I have a parent-child relationship with a hasMany that’s “async: true”. I ran into an edge case where sometimes a user can delete the model while it’s in the process of loading up the hasMany. In that case, should the promise be automatically cancelled?

The code looks something like (I’m using ember-cli and I’ve omitted the ES6 import/export statements)

# models/my-parent.coffee
MyParent = DS.Model.extend
   name:       DS.attr('string')
   myChildren: DS.hasMany('my-child', async: true)

   doStuff: (->
     @get('myChildren').then (children) =>
       # there's a race condition where sometimes this callback
       # is triggered after the parent model has been deleted!
       return if @get('isDeleted')

       # ... do stuff on children ...

   ).observes('name')

I’m more than happy to work on a patch if that’s something that would be useful!

Cheers,

Nik


#2

You can’t “cancel” a promise, but the resulting fulfillment can be ignored.

I would recommend considering not doing ajax as a response to observers changing, in the observer callback it is entirely unclear to you why name changed and if it actually did change. If the CP for name invalidates, it may turn out to be the same name as previously.

Typically you don’t want to do stuff with side-effects this way, rather on consumption of some property or action or method invocation.


#3

Hey Stefan - first off, thanks for your help!

I’m actually updating a property on the parent model based on the names of the children - so the observer should be:

    doStuff: (->
      # ...
    ).observes('children.@each.name')

If I understand what you’re saying, maybe that logic actually belongs in the child model? I’ll go and have a think in either case :smile:

Again, appreciate the help!