Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load belongsTo/hasMany relationships in route with EmberJS

In my EmberJS application I am displaying a list of Appointments. In an action in the AppointmentController I need to get the appointments owner, but the owner always returns "undefined".

My files:

models/appointment.js

import DS from 'ember-data';

export default DS.Model.extend({
    appointmentStatus: DS.attr('number'),
    owner: DS.hasMany('person'),
    date: DS.attr('Date')
});

models/person.js

import DS from 'ember-data';

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

templates/appointmentlist.js

{{#each appointment in controller}}
    <div>
        {{appointment.date}} <button type="button" {{action 'doIt'}}>Do something!</button>
    </div>
{{/each }}

controllers/appointmentlist.js

export default Ember.ArrayController.extend({
    itemController: 'appointment'
});

controllers/appointment.js

export default Ember.ObjectController.extend({
    actions:{
        doIt: function(){
            var appointment = this.get('model');
            var owner = appointment.get('owner'); //returns undefined
            //Do something with owner
        }
    }
});

Now, I know I can change the owner-property to owner: DS.hasMany('person', {async: true}), and then handle the promise returned from appointment.get('owner');, but that is not what I want. I have discovered that if I do this {{appointment.owner}} or this {{appointment.owner.name}} in the appointmentlist template, the owner record is fetched from the server. So I guess Ember does not load relationships unless they are used in the template.

I think that the solution to my problem is to use the appointmentlists route to fetch the record in the belongsTo relationship. But I can't figure out how.

Maybe something like this?

routes/appointmentlist.js

export default Ember.Route.extend({
    model: function() {
        return this.store.find('appointment');
    },
    afterModel: function(appointments){
        //what to do
    }
});

EDIT

I did this:

routes/appointmentlist.js

export default Ember.Route.extend({
    model: function() {
        return this.store.find('appointment');
    },
    afterModel: function(appointments){
         $.each(appointments.content, function(i, appointment){

                var owner= appointment.get('owner')   
         });
    }
});

and it works, but I do not like the solution...

like image 924
Karoline Brynildsen Avatar asked Aug 19 '14 11:08

Karoline Brynildsen


People also ask

What are polymorphic models in Ember?

Polymorphism. Polymorphism is a powerful concept which allows a developer to abstract common functionality into a base class. Consider the following example: a user with multiple payment methods. They could have a linked PayPal account, and a couple credit cards on file.

Which of the following Cannot be a reflexive relationship in Ember?

<br> `therefore` 512 cannot be the number of reflexive relations defined on a set A.

What is store in Ember?

One way to think about the store is as a cache of all of the records that have been loaded by your application. If a route or a controller in your app asks for a record, the store can return it immediately if it is in the cache.

What is service in Ember?

A Service is an Ember object that lives for the duration of the application, and can be made available in different parts of your application. Services are useful for features that require shared state or persistent connections. Example uses of services might include: User/session authentication. Geolocation.


1 Answers

You are still asynchronously loading those records, so if you are fast enough you could still get undefined. It'd be better to return a promise from the afterModel hook, or just modify the model hook to do it all.

model: function() {
  return this.store.find('appointment').then(function(appointments){
    return Ember.RSVP.all(appointments.getEach('owner')).then(function(){
      return appointments;
    });
  });
}

or

model: function() {
  return this.store.find('appointment');
},
afterModel: function(model, transition){
  return Ember.RSVP.all(model.getEach('owner'));
}
like image 100
Kingpin2k Avatar answered Nov 25 '22 15:11

Kingpin2k