Correct use of DS.store.load


#1

I’m in the process of updating one of our production Ember 0.9 apps to the latest RC.6 version, and am having an issue with our use of DS.store.load() to update a model with new JSON returned by the server.

Our record looks something like this in CoffeeScript, with a number of embedded associations.

App.Person = DS.Model.extend 
  name: DS.attr('string')
  items: DS.hasMany('App.Item', embedded: 'always')
  details: DS.belongTo('App.Details', embedded: 'always')

On this same Person model we’re using an ajax call to save to the server and it returns us back the updated Person JSON plus the embedded elements.

  completeThing: (data, callback = null) ->
    $.post("completeThing",
           { person: data.person},
           (data) => @reload(data, callback))

  reload: (data = null, callback = null) ->
    App.store.load(App.Person, data)
    callback?()

So I call completeThing and when the ajax call returns it gets data which contains an updated json representation of our Person model, including the updated embedded elements.

Previously the App.store.load() call would update our model with the returned data. Now I’m finding it has no effect, so I’m wondering it that’s still the recommended way to load updated JSON for a model.

I’ve tried using App.store.updateRecordData() which does update the attributes on App.Person but not the embedded ones like details or items, plus it’s tagged as @private so I’m not sure I should be calling it.

Thanks.


#2

I don’t have an answer but just suggestions for you to try:

First, change the way you are embedding association. You should use the current approach, read this link

 App.store.adapter.serializer.map "App.Person",
   details:
     embedded: "always"

Now my suggestions for loading data via ajax

1. If you have App.PersonRoute, you can also move the ajax call and data loading there and try:

store.adapterForType(App.Person).load(store, App.Person, payload); as discussed in the links below. This API will also handle sideloaded and embedded data. This is documented in the 1st link below. Note they may be outdated

documentation link for the above

The `1st comment’ in the link below mentions that using DS.Store.load seems outdated.

Loading data into the store from an AJAX request: https://github.com/emberjs/data/issues/649

2. You can try moving the call to the controller. The link below uses RC 4 and loads data using App.Store.load but from the controller.

3. Some useful link:

the link below uses DS.defaultStore.load to achieve similar aims:

Pls post back your solution.


#3

Thanks for the helpful response @yyy

For the record the winning answer is:

  store.adapterForType(App.Person).load(store, App.Person, payload);

it’s even documented in BREAKING_CHANGES.md

So the full code I needed was

# Define the store with mappings for embedded elements
App.Store = DS.Store.extend()

DS.RESTAdapter.map 'App.Person',
  details: { embedded: 'always' }
  items:    { embedded: 'always' }

App.store = DS.Store.create()

# Define a model with the embedded elements
App.Person = DS.Model.extend 
  name: DS.attr('string')
  items: DS.hasMany('App.Item', embedded: 'always')
  details: DS.belongTo('App.Details', embedded: 'always')

# Use the adapter to load the JSON in the callback
App.store.adapterForType(App.Person).load(store, App.Person, payload);

It’d be awesome if this got included in the official documentation and the load function on DS.Store gets deprecated or at least points to the new way of loading data.


#4

Great to hear it was helpful. Thanks for posting back what worked.