Building Ember Models from one API call


#1

Currently, I get all the JSON from the server in one API call. I’m wondering, how can I make multiple models to use for the different routes from this? The way I’m currently doing it is by putting it in a huge model, and then accessing the smaller parts from the different routes. Would this be the right approach?


#2

James, what you’re asking for isn’t quite clear. Could you explain a little more? You might start by posting your code for examination. Start with your Model set up.

Are you asking to make multiple Ember models from a single set of JSON? Are the models all of the same type, or are you looking to create a Person model, a Shirt model, and a Button model all from a single packet?

If so, then you might consider refactoring your models with hasMany or belongsTo relationships. If you can do that, then Ember will do much of that work on your behlaf.


#3

Yes, I am trying to make multiple models from a single set of JSON. Blocks.Model is set to this JSON when it’s loaded.

{
"client":{
    "people":{
        "primaryPerson":{
            "@id":"02c6486ac0a8017400088f851bdad13c",
            "firstName":"Mr",
            "lastName":"XSD-TEST",
            "birthday":"1971-12-30",
            "gender":"MALE",
            "personType":"PRIMARY"
        },
        "spouse":{
            "@id":"02c6486ec0a8017401ad582291fbc1d0",
            "firstName":"Mrs",
            "lastName":"XSD-TEST",
            "birthday":"1968-09-13",
            "gender":"FEMALE",
            "personType":"SPOUSE"
        },
        "child":[
            {
                "@id":"02c6486fc0a8017400dee3ee8f9cc058",
                "firstName":"Abe",
                "lastName":"XSD-TEST",
                "birthday":"2003-02-17",
                "gender":"MALE",
                "personType":"CHILD"
            },
            {
                "@id":"02c6486fc0a8017401f554906569c0d4",
                "firstName":"Boo",
                "lastName":"XSD-TEST",
                "birthday":"2006-05-06",
                "gender":"MALE",
                "personType":"CHILD"
            }
        ]
    },
    "events":{
        ....
    }

What I’m currently doing in the router is this, which I feel is not correct:

Blocks.TimelineRoute = Ember.Route.extend({
model: function() {
    return Blocks.Model;
}.observes("Blocks.Model"),
setupController: function(controller, model) {
    this.controllerFor('addNewPerson').set('model', model.client.people);
    this.controllerFor('modifyPerson').set('model', model.client.people);
    controller.set('content', model.client);
}
});
Blocks.EmploymentRoute = Ember.Route.extend({
model: function() {
    return Blocks.Model;
}.observes("Blocks.Model"),
setupController: function(controller, model) {
    // Adding/Modifying people modals.
    this.controllerFor('addNewPerson').set('model', model.client.people);
    this.controllerFor('modifyPerson').set('model', model.client.people);
    // People selection view
    this.controllerFor('peopleSelection').set('model', model.client.people);
    this.controllerFor('employmentEvents').set('model', model.client.events.event);
    this.controllerFor('employmentDropdown').set('model', model.client.details.employment);
    controller.set('content', model.client.details.employment);
}

});


#4
  1. Do you have control over the return format of your JSON? Are you using Ember Data? If you’re using Ember Data, and you have control over your own return format, then you’re going to be far better off letting Ember Data manage the creation of models for you.

  2. You list “people” and have them side by side (and named) as if they have a relationship to each other. But nothing in their data indicates that they pair up. Same with the children. I assume this data is supposed to model a standard family unit? If so, then it might be easier to just add properties to each person indicating relationship status, then you can simply return 4 people without having to rely on nested data.

Something like this could work. Note that I removed the personType attribute because if you’re specifying a parent ID then it’s implicit that user is a child.

{
    "client":{
        "people": [
            {
                "@id":"02c6486ac0a8017400088f851bdad13c",
                "firstName":"Tarzan",
                "personType":"PRIMARY",
                "parent1": undefined,
                "parent2": undefined
            },
            {
                "@id":"02c6486ac0a8017400088f851bdad13c",
                "firstName":"Jane",
                "personType":"PRIMARY",
                "parent1": undefined,
                "parent2": undefined
            },
            {
                "@id":"02c6486ac0a8017400088f851bdad13c",
                "firstName":"Abe",
                "parent1": '02c6486ac0a8017400088f851bdad13c',
                "parent2": '02c6486ac0a8017400088f851bdad13c'
            },
            {
                "@id":"02c6486ac0a8017400088f851bdad13c",
                "firstName":"Boo",
                "parent1": '02c6486ac0a8017400088f851bdad13c',
                "parent2": '02c6486ac0a8017400088f851bdad13c'
            },
        ]
    }
}

Note that there are also potential issues with that (as well as your solution) from a data perspective. If a user is in the system as a child, what happens when they’re no longer a child? What happens when they get married and have their own children? You’d have to change your personType field.

Anyway, to answer your actual question, the simplest thing to do would be to create Person models from the primaryPerson and spouse objects, loop over the child array to see if there are children, and create Person models from everything in that array. Something like this:

if (client.people.primaryPerson) {
    // create Person model
}
if (client.people.spouse) {
    // create Person model
}

client.people.child.forEach(function(){
    // create Person model
});