lzc
lzc

Reputation: 1705

What's the best way to map objects into ember model from REST Web API?

The topic of this post is: my solution is too slow for a large query return.

I have a Web Api serving REST results like below from a call to localhost:9090/api/invetories?id=1:

[
 {
  "inventory_id": "1",
  "film_id": "1",
  "store_id": "1",
  "last_update": "2/15/2006 5:09:17 AM"
 },
 {
  "inventory_id": "2",
  "film_id": "1",
  "store_id": "1",
  "last_update": "2/15/2006 5:09:17 AM"
 }
]

Since my WebAPI did not provide a root key for my JSON response, I made a RESTSerializer like following.

export default DS.RESTSerializer.extend({
  extract:function(store,primaryType,payload,id,requestType){
    var typeName = primaryType.typeKey;
    var data = {};
    data[typeName] = payload; // creating root
    payload = data;
    return this._super(store,primaryType,payload,id,requestType)
  }
});

When this gets run, I get the following error message: Assetion failed: You must include an 'id' for inventory in an object passed to 'push'

As you can see, these objects do not have the attribute id, so I found that the default behaviour of Ember RESTSerializer forces me to write my own.

Okay, so here's where I'm not sure my solution is right. inventory_id from my return is unique, therefore I choose to use that as an id, okay I'm thinking to my self, I'll just add it manually. The function looks like this now:

export default DS.RESTSerializer.extend({
  extract:function(store,primaryType,payload,id,requestType){
    var typeName = primaryType.typeKey;
    for(var i=0;i<payload.length;i++){
      payload[i].id = payload[i].inventoryId;
    }
    var data = {};
    data[typeName] = payload; // creating root
    payload = data;
    return this._super(store,primaryType,payload,id,requestType)
  }
});

By just manually duplicating an attribute, I feel like I'm cheating my way over this error message. In addition, I sometimes return a large payload array (over 150k rows). Looping O(n) just doesn't seem a right price to pay for just a simple mapping.

Is there some other way to set either my WebAPI or serializer up so I avoid the for loop in assigning the id that ember so desperately wants.

Upvotes: 1

Views: 361

Answers (1)

neciu
neciu

Reputation: 4485

I think this should fix your problem:

export default DS.RESTSerializer.extend({
    primaryKey: 'inventory_id'
});

With this parameter Ember Data will map inventory_id to it's id parameter.

Upvotes: 2

Related Questions