The store is the main interface we’ll use to interact with our records as well as the backend. When we create, load, or delete a record, it is managed and saved in the store. The store then takes care of replicating any change to the backend.
We won’t cover all of the functions, but we’ll go over the more common ones and their gotchas.
peekAll
store.peekAll is similar to store.findRecordAll, but instead of making a request to the backend it
returns all the records already loaded in the store. The result of this method is a live array, which means it will update its content if more records are loaded into the store for the given type.
Let’s study this with the inspector by navigating to http://localhost:4200 and clicking refresh. Next we’ll grab an instance of the application route and run the following commands in the console: friends = $E.store.peekAll('friend')
friends.get('length')
> 0
friends.mapBy('firstName')
> []
We stored the result in a variable called friends, which is a collection with zero element. This makes sense because we haven’t loaded any friends yet. If we click on the friends link and run the following: friends.get('length')
> 3
friends.mapBy('firstName')
> ["zombo Wamba", "Pizza", "Loading-this"] ⁸³http://emberjs.com/api/data/classes/DS.Store.html
We’ll see that the result is no longer zero. When we navigated to the friends route, a request to the backend was made and some records were loaded into the store. As we mentioned, the result from peekAll is a live array. That’s why our friends variable was updated without requiring any additional steps.
XHR logging in the console is a great way to debug our applications. We can enable it using the setting in Chrome’s DevTools. See slide #4 in the presentation [Wait, DevTools could do THAT? by Ilya Grigorik](https://www.igvita.com/slides/2012/devtools-tips-and- tricks/#4](https://www.igvita.com/slides/2012/devtools-tips-and-tricks/#4).
findAll
If we call findAll with a model name, then it will make a request to load a list of records of that type. The following is an example:
friends = $E.store.findRecordAll('friend')
XHR finished loading: GET "http://localhost:4200/api/v2/friends".
If we want to send query parameters with the request, then we should usestore.query, it receives the name of the model and an object as second argument, every key on the object will be included as parameter:
friends = $E.store.query('friend', {hasArticles: true, sort_by: 'created_at'}) XHR finished loading: GET "http://localhost:4200/api/v2/friends?hasArticles=true\ &sort_by=created_at".
In the previous request we asked query to load all the articles, sending as parameters the keys
hasArticles and sort_by.
Like peekAll and filter, the result from findAll is a live array. When called, it makes a request to the server and the collection is updated when more records are added to or removed from the store.
findRecord: Loading a single record
If we want to load a single record then we should use store.findRecord . To do that, we use the name of the model and the record’s id as second argument:
$E.store.findRecord('friend', 15)
XHR finished loading: GET "http://localhost:4200/api/v2/friends/15".
In the previous example, we loaded the friend with id 15. The store will only make a re- quest to the server if the friend is not available in the store. To understand this, let’s go to http://localhost:4200/friends and try the following in the console:
id = $E.store.peekAll('friend').get('firstObject').id
$E.store.findRecord('friend', id)
If we open our network tab, we’ll see that the store didn’t make any requests this time. This is because we asked for a friend who was already loaded into the store.
It’s important to mention that findRecord and peekAll return promises. When testing on the browser’s console, we don’t have to worry about it, but if we want to use the result in our application then we need to keep this in mind.
peekRecord
We can use store.peekRecord(‘friend’, 15) to fetch a user directly from the store. Unlike findRecord, query or findAll, the behavior of this function is synchronous. It will return the record if it is available, or null otherwise.
metadataFor
If our API includes a “meta” key with a response, we can access such metadata with the metadataFor function. This is useful when we implement things like pagination.
Suppose the response from our API is something like the following when we fetch all of our friends: {
friends: [ ... ],
meta: { total: 30} }
We can then read the meta key doing this.store.metadataFor(‘friend’);
createRecord
We are already familiar with createRecord, which is used when we want to create a new record for a given type. For example:
this.store.createRecord('friend', {attrs..});
We can also use createRecord via a relationship. Suppose we are in the context of a friend and we know they have an articles property that represents all the articles belonging to another friend. If we want to add a new article, we can do it using the following syntax:
friend.get('articles').createRecord({attrs...}); This won’t work if the relationship is async.