belongsTo relation call returns null within observer


#1

Hi,

I have belongsTo relation on a model:

//book.js
export default DS.Model.extend({
    name: attr('string'),
    item: belongsTo('item', {async: true}),
});

//item.js
export default DS.Model.extend({
    name: attr('string')
});

When I call:

let b = store.createRecord('book', {name: 'test'});

b.save().then(function(b) {
  //b is saved correctly here

  b.get('item').then(function(item) {
    
  //item relation is gotten successfully - all works well

 });

});

(NOTE: I’m not initially setting the item relation when creating the book record, because this is determined by the backend response)

…everything works as expected so far.

now, somewhere else I have an observer that fires when a change to a books array is made.

when it fires I’m iterating over the books array with the newly saved book and calling the relation item the exact same way as I do right after saving the book.

but for some reason item relation on the book record is always null within the observer.

booksChanged: on('init', observer('books.[]', function() {
   
//this gets triggered
    let b = this.get('books').get('firstObject');//->just assume the book created is the first object
   
   b.get('item').then(function(item) {
     
     //item is null, why???

   });
   

}));

version 2.7 ember and ember-data.

any thoughts?

thanks


#2

Observer is fired when books changed, but it is not guarantied that items are ready and resolved in the promise.

Could you avoid using observer? For example with an action which would be fired when items are resolved after save? Or could you reditect to this route or a subroute after save, so model hook in the route handler can wait for the promise?

Actually, books and items will be updated automatically, so if you use them with computed property, it should be updated also, so you dont have to observe.

If you can reduce the usage of observers, better, because they quite often cause suprises.


#3

Hi,

Yes, you’re correct, they are updated automatically.

But the problem is that I need to take the array and process each book along with the item relations, and output something else (into a different data structure), then render that output into the template.

So the data structure needs to be changed.

I’m thinking now of simply sending an action up when the save occurs (along with the resolved relations). Or to let the promises resolve within the template for the relations.

Anyhow, thank you for the response, great advice.