Series: Introduction to Ember Data 2.0

Ember Data 2.0-Getting Data from the Server with findRecord and findAll

Published on Dec 04, 2015

In this second installment of our Ember Data 2.0 series, we go over two of the most common ways to get data from the server: findRecord and findAll.

Along the way, we’re introduced to the store, and discover that Ember automatically calls findRecord for us in some routes.


Links

Code

Find all of the monsters on the server:

model(){
  return this.store.findAll('monster')
}

Find one particular monster (this is the default model method in routes with params):

model(params){
  return this.store.findRecord('monster', params.monster_id)
}

Transcript

In the last episode, we showed how to set up Ember data and how to make our DS models. This week, we’ll talk about the two most common ways to get data from the server, starting with findAll.

So the store is where we’re going to put all the data after we have it from the server. It is a data store, very well-named. And this store gives us a lot of very useful methods. We’ll be looking at findAll and findRecord today, and some of these other ones soon.

How it fits in is the store sits just outside of your application, I mean it’s in it, but we can think of it as separate, and then it interacts with the Cloud, with our server, through the adapter. So no matter which adapter you use, you’ll still interact with the store the same way. That’s really useful, because that means that if you need to change adapters, you won’t have to change much code within your application.

So now we know what the store is, and the store is automatically available on all routes. You can get to it on other Ember objects by injecting it. It’s now a service.

So on the store, we can call findAll, and it’s going to find all of the type monster, as described here in our models/monster.

So you ask the store to findAll monsters, and then it’ll go to the adapter, here the ActiveModelAdapter, and we've only defined it in an application, you can specify different adapters per model. We haven’t done that here. We’ll get to that in a later video in this series. So the ActiveModelAdapter knows how to ask the server for information.

So this is the path that it’s having. The application calls findAll on the store, the store calls findAll on adapter, and then it sends an Ajax request to your server, and your store and your application are getting back promises.

So this is the XHR request that our adapter is sending. There’s a lot there. We can see that it’s a GET one, it is being sent to a certain URL, and this is a lot of stuff that I’m really glad we did not have to worry about. But of course if you do want to change this stuff, there are ways to do it which we’ll cover later in the series.

So you send that request to the Cloud, and then you get it back and it resolves the promises. Now for the purposes of this router, we can think of it as just returning an array. But it actually returns a DS.AdapterPopulatedRecordArray, and through all that magic... Well, it returns monsters and team memberships, because that’s how our ActiveModelAdapter works.

And somehow, notice that it’s only calling monsters, it’s not calling team memberships. Ember data has both monsters and team memberships. So somewhere in here it adds them both to the store. If we trace the promises we can see that it happens in something called ‘Extract payload’, which we won’t discuss this episode. For now you can just think of it as magic, but there is a method to this magic and if you dig deep in Ember, you will always find what’s happening. It’s never truly magic.

Anyways, this findAll and the monsters model, including the hasMany relationship with team members, is enough to get the monsters and the team members into the store and useable by you. I’m very glad I don’t have to do that myself.

So now our second method of the day, findRecord. We’re already calling findRecord. It’s just happening automatically. The default model method in a route calls findRecord on the name of the route, monster in this case, and it takes the monster ID. So if we build this out, then this will end up doing the same thing as just not defining the model.

If you want to demonstrate this, then you could remove what’s happening here, and we’ll see that this ends up making this route not work. So what used to be a findRecord, either explicitly or by default, if you remove that line it doesn’t work.

So findRecord acts a lot like findAll. It takes the type of record it wants, but then it also takes an ID, and it’s going to use that ID to get just one record from the server.

But you’ll notice something interesting. If we go to our network, we’ll see that... here yes, it did call the monsters too. Here is what it gets back, just a single monster as well as an array of team memberships. But then when we change, it’s not calling any more, and that’s because findRecord, it first checks the store to see if it’s already there.

So it’s illustrated here, if it’s already in the store, it resolves immediately. This is an example of the caching that Ember data does for you that can save you a lot of time when you’re navigating around your application.

Of course you may be wondering why... if the monsters, the findAll was called before the findRecord for two, why was this called at all? And presumably that’s because these promises weren’t resolved by the time this call was made.

So there you have it, findAll and findRecord. These are the two most common ways of grabbing data from the store, and they’ll get you a long way when you’re doing read-only things with Ember data.

Next time, we’ll talk more about the store and the cache, and different ways we can manipulate it. I’ll see you then.

Introduction to Ember Data 2.0

Subscribe to our mailing list