Welcome to weblogs.com.pk Sign in | Join | Help

Ember: Master Detail and Round-tripping

Lets go deep and add Master Detail and Round-tripping into our Ember application that we have been developing

Lets add two routes; /invoice and /invoice/edit-item; and this time we are using –pod (dash dash pod) so that view (hbs template) and controller (route.js) gets created in the same folder


  • Note how we have specified sub route invoice/edit-item
  • Note how we have updated the app\router.js code to specify the need of id parameter in the new routes

Idea is that invoice has “line items” and one invoice can have more than one line item. From the existing invoices view we will select an invoice and invoice route will display the invoice detail and from there we can edit the line item using invoice/edit-item route. Lets add item model and extend our existing invoice model accordingly


  • Note how item.amount field is defined; its a computed property, note how price and quantity fields are mentioned at the end; the amount field depends on those properties and changing them also change amount and specifying them tells the template to get the newer amount field; kind of INotifyProperyChanged interface from WPF / Silverlight
  • Note how invoice model is extended and now it has “hasMany” items field and also note amount field is now also computed property that sums up all the amounts of its item, also note how dependent property is defined for this!

Next lets implement the two newly added routes; invoice/route.js and invoice\edit-item\route.js


  • Note how we can use the params.id in our router.model; if its set in the router.js; we can have more than one parameters if we want to!
  • Note how invoice/route.js has specified adapterOptions to also include items; if we dont specify this; the adapter will send 1+N calls; where N is number of items an invoice has; with this adapterOptions in place; we can use the JSONAPI’s relationships and send the dependent objects in the single go
  • Note the use of actions; we can have one or more actions in the router that we can call from the view; here we are using save actions that we will call when user will click the Save action button in the view to update the invoice line item. Also note that model.save() is called to save the model (invoice line item in this case) and Ember Data will automatically call the configured backend API accordingly (PATCH call to update) and this being a promise we can use “then” and specify the function what to do next; and we are transitioning the user back to the invoice view!

Lets implement our views; given edit-item is sub route of invoice; we can have a view where invoice details are shown and from there if user edit an invoice item the edit-item view gets loaded inline


  • Note that we are passing item.id to edit-item sub route; so if an invoice with id 1 has two items say with id 5, 6 our edit-item route will become /invoice/1/edit/5 and so on

We now need to update the Mirage code so we can test things out. For this first we need is a new factory for item; its on same pattern as invoice factory. Second, we need to establish the relationship between the invoice and item; we need to update mirage\scenarios\default.js like so:


  • Note that we have created an invoice using server.create; and then used its id to pass to server.createList as a parameter; this way we can create a list with one particular value; also note that invoice_id field is not defined in the item factory; instead its mixed in here and we can use it to query in the mirage\config.js later

And lastly we need to add new action URLs into our mirage\config.js. We need invoices/{id} that will return the particular invoice along with its dependent items, we will need items/{id} that will get called when editing invoice line item and patch for items/{id} that Ember Data calls when we save the model


  • Note how we used item.invoice_id field to query related data
  • Note how we have used “relationships” and “included” elements to specify which are depended items and can include them in the same call
  • Note the implementation of the patch() and how JSON.parse is used to get the value from the request and updated into Mirage and then the updated value is returned that Ember Data expects
  • there appears to be some kind of bug in Ember or its adapter due to which we have to send all the attributes of the items in the “data.relationships” as well as “included”; ideally only ids of items should be sufficient in data.relationships and all attributes of child objects only in “included” root!


The code is made available @ https://github.com/khurram-aziz/HelloEmber

Published Saturday, March 5, 2016 4:14 PM by khurram
Filed under: ,


No Comments

New Comments to this post are disabled