8

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
  • 2,824
  • 1
  • 29
  • 59

4 Answers4

9

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.

andorov
  • 4,197
  • 3
  • 39
  • 52
  • 2
    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 Nov 07 '13 at 02:10
  • This was posted over a year ago and still works perfectly today, I'm guess that this is here to stay. – Ash Blue Dec 21 '15 at 18:30
7

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.

emk
  • 60,150
  • 6
  • 45
  • 50
  • Thanks! I was close to `didFindRecord` but I'm not sure I fully knew what was going on with that method. – bschaeffer Apr 09 '13 at 17:56
  • Hi. This turnaround works very well while I am populating a single record. How can I populate multiple records? For example: http://pastebin.com/raw.php?i=NNFVDYR0 – Mattia May 11 '13 at 14:18
  • 1
    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: http://stackoverflow.com/a/18948134/1477165 – bfcoder Nov 07 '13 at 02:11
  • In more recent versions of ember/ember-data this is now achieved using `store.pushPayload` (http://stackoverflow.com/a/35356634/621809). – Ernesto Dec 06 '16 at 12:23
5

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

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

Yossi Shasho
  • 3,632
  • 31
  • 47
0

All answers above did not work for me. What only worked for me was:

this.store.buildRecord(this.store.modelFor('person'), data.id, data)
Sami
  • 5,819
  • 1
  • 23
  • 30