Load a model manually with EmberData

10,093

Solution 1

Supposedly, the official way to do this is using adapter.load, as described in this thread:

Loading Data

Previously, some features of the store, such as load(), assumed a single adapter.

If you want to load data from your backend without the application asking for it (for example, through a WebSockets stream), use this API:

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

This API will also handle sideloaded and embedded data. We plan to add a more convenient version of this API in the future.

But unfortunately, it doesn't handle sideloaded data, despite what the documentation claims. I personally use something like the following, which is based on how find(ID) is implemented:

var id = json["person"]["id"];
var store = DS.get("defaultStore");
var adapter = store.adapterForType(App.Person);
adapter.didFindRecord(store, App.Person, json, id);
var person = App.Person.find(id);

Note that this code assumes JSON in the same format that find(ID) expects to receive from the server, as documented in the RESTAdapter guide:

{
  person: {
    id: 1,
    is_private: false,
    projects: [3]
  },
  projects: [
    { id: 3, name: "FooReader" }
  ]
}

This will apply any transformations you've configured using keyForAttributeName (such as mapping is_private to isPrivate), and it will handle sideloaded records. I'm not sure if this is a best practice, but it works quite well.

Solution 2

As of a few days ago in ember data 1.0 beta you can use pushPayload to load data directly into the store. For example if you get data pushed to your app through WebSockets (we use the Heroku add-on Pusher). You can call it on the store (source) directly and it will pass it through the appropriate serializer:

var postsJSON = {
  posts: [
    {id: 1, post_title: "Great post"}
  ]
}

this.store.pushPayload('post',postsJSON)

NOTE that it will not currently load a singular object (ie post: {id: 1, post_title:"First!"}) - you need to format it as plural with an array.

DS.RESTSerializer has pushPayload as well (source), in which case you need to pass it the store instead.

I highly encourage reading the source code before using, as it looks like the implementation of it will be revisited.

Solution 3

how about store.push('user', userJSON)?

http://emberjs.com/guides/models/pushing-records-into-the-store/#toc_pushing-records

Share:
10,093
bschaeffer
Author by

bschaeffer

Updated on June 27, 2022

Comments

  • bschaeffer
    bschaeffer almost 2 years

    I have an Ember app with a login form which returns the current user in JSON format after successful login.

    Using createRecord sets the returned JSON attributes directly on the model. For instance, is_private becomes user.is_private, not user.get('isPrivate')?

    How do I load the user model so that the attributes are set correctly and I don't have to re-fetch it using the id?

  • bschaeffer
    bschaeffer about 11 years
    Thanks! I was close to didFindRecord but I'm not sure I fully knew what was going on with that method.
  • Mattia
    Mattia almost 11 years
    Hi. This turnaround works very well while I am populating a single record. How can I populate multiple records? For example: pastebin.com/raw.php?i=NNFVDYR0
  • bfcoder
    bfcoder over 10 years
    I fully expect this to break sometime, but at least it is something that works for now. I hope it doesn't. I did have to turn my json into a plural with an array for just the single object.
  • bfcoder
    bfcoder over 10 years
    And as far as I can tell this no longer works in ember-data 1.0.0-beta.3 I was using this in ember-data 0.14 but I ended up using the answer andorov gave with 1.0.0-beta.3: stackoverflow.com/a/18948134/1477165
  • Ash Blue
    Ash Blue over 8 years
    This was posted over a year ago and still works perfectly today, I'm guess that this is here to stay.
  • Ernesto
    Ernesto over 7 years
    In more recent versions of ember/ember-data this is now achieved using store.pushPayload (stackoverflow.com/a/35356634/621809).