Accessing values via DS.belongsTo()


#1

I have a model city defined like this:

// app/models/city.js
import DS from 'ember-data';

var City = DS.Model.extend({
    name: DS.attr('string'),
    province: DS.belongsTo('province', {async: true})
});

As well as a model province defined like this:

// app/models/province.js
import DS from 'ember-data';

var Province = DS.Model.extend({
    name: DS.attr('string')
});

In my template I can view the cities and provinces like this:

{{!-- app/templates/cities/index.hbs --}}
<tbody>
  {{#each city in controller}}
    <tr>
      <td>{{city.name}}</td>
      <td>{{city.province.name}}</td>
    </tr>
  {{/each}}
</tbody>

From within my controller I would also like to access the province names.

// app/controllers/cities/index.js
import Ember from 'ember';

export default Ember.ArrayController.extend({
  sortProperties: ['name'],
  sortAscending: true,
   ...
  someFunction: function() {
    var cities = this.get('model');
    cities.forEach(function(city) {
      var name = city.get('name');
      var province = 'unknown';
      var promiseObject = city.get('province');
      promiseObject.then(function() {
        province = promiseObject.get('name');
        console.log('Inside promise: province='+province);
      });
      console.log('Outside promise: province='+province);
    });
  }
});

Inside the promise the value of province is set correctly, but when I log the value outside I see that it is still unknown.

What am I doing wrong and is there a better more elegant way to access values via DS.belongsTo?


#2

You’re misunderstanding promises. The main function of a promise is to allow for asynchronous operations to occur without blocking execution. That means the function you passed into promiseObject.then isn’t required to run before execution can move to the next line, in your case console.log('Outside promise: province='+province);

If you know the promise has already been resolved you can call city.get(‘province.name’) and it should work. If you don’t know the promise has been resolved then you have no choice but to do your logical work inside of a then function. To this end it maybe helpful to use RSVP.all to resolve all your promises before doing your logical operations.


#3

I moved all of the assignments to within the .then(function(){// here }) and it works fine.

Seems a bit awkward having to do this and would expect a more elegant manner, but this will do for now thanks.