Matt Blair

Matt Blair

I read that you learn more from a poor example than from a correct one. I don't believe this but that means my site will be a success.

Ember.Data Promise-Aware Properties (Cheaters Edition)

Ember.Data Promise-Aware Properties (Cheaters Edition)

1-Minute Read

I have models like this:

Models

App.Child = DS.Model.extend({
  parent: DS.belongsTo('parent', {async: true})
});

App.Parent = DS.Model.extend({
  children: DS.hasMany('child', {async: true})
});

App.Nursery = DS.Model.extend({
  children: DS.hasMany('child')
});

Then a controller like this:

###Controller

App.NurseryController = Ember.Controller.extend({

  uniqueParents = function() {
    return this.get('children').mapBy('parent').uniq();
  }.property('children'),

  somethingLikeReliesOnUniqueParents = function() {
   ....
  }.property('uniqueParents')
}

The Problem

The property somethingLikeReliesOnUniqueParents was never getting unique values. I found two problems here:

  1. uniq() couldn’t figure out uniqueness - much like the problems with filter.
  2. The parents promises, once they resolved, weren’t updating properties that relied on them.

The first problem I solved the same way I solved in the filter case - filter uniqueness by id, not by object.

The second problem I found a somewhat hacky workaround. All promises in the system have a isFulfilled flag. Setting the properties to observe that field allowed the properties to update.

The Solution

My code ended up looking like this:

###Controller

App.NurseryController = Ember.Controller.extend({

  uniqueParents = function() {
    return this.get('children').mapBy('parent').uniq(function(parent) { return parent.get('id'); });
  }.property('children'),

  somethingLikeReliesOnUniqueParents = function() {
   ....
  }.property('uniqueParents.@each.isFulfilled')
}

This solved the issue and still allowed the async behavior I was looking for.

Recent Posts

Categories

About

This theme was developed for Hugo.