Series: Introduction to Ember Data 2.0
Serializers-How are normalize and normalizeResponse different?
Published on Apr 27, 2016
normalize and normalizeResponse are both used when munging the JSON response, but the Ember Data Serializer calls them at different times in the normalization process.
Learn when to use each.
Links
Code
//serializers/quote.js
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
normalize(modelClass, resourceHash){
resourceHash.id = resourceHash.id.replace('quote_', '');
return this._super(...arguments)
}
})
Transcript
Hey everyone. Today we’re going to continue our series on the serializer class in Ember data 2.0. Specifically we’re talking about how to customize the JSON API Serializer version of it, which is descended from the plain serializer. But if you’re using the REST serializer or the active model serializer, you should be able to use most of what we talk about.
So last week we talked about the normalizeResponse
method, as well as all the child methods that have normalize
, some type of thing, Response
. But there was one method we didn’t go over, and that’s normalize
. And so you may be wondering, why would we use normalize
? What is that good for?
normalizeResponse
as well as the other methods in that family, are primarily concerned with the response as a whole. You can see this by the fact they ask for the primaryModelClass
and the requestType
, and that’s how they sort out which of these secondary methods they’ll send it to, is through the requestType
. And the id
, that’s the main id
of the request. So we’re looking at the entire thing. normalize
on the other hand is just for one JSON API object. So what’s the difference between that? So here, this book is a JSON API object, everything between this and this. But also this quote is a JSON API object, as is this quote and this quote and this quote. So here we have five JSON API objects, and it’s going to process each of these individually with a normalize
method.
Let me prove that to you. We’re going to put a normalizeResponse
and a normalize
method in both the book and the quote serializer, and we’re going to log out once for every time that we go in there, and we’ll see how often each one is called. So we’ll go ahead and go to our books
route and we’ll see that normalizeResponse
is called once for the book because that is the response that we’re getting from the books
route. Then normalize
is called three times, once for each book, and then normalize
is called for quote
nine times, once for each quote. And if we do it for quotes
... Okay, there are two things here. If we scroll up, we’ll see that we get the normalizeResponse
for a quote once, because that gets called once per response, then we get nine quotes, and then we get some errors. And that’s because... well, we have the model name kindling
and we fixed it in the /books
in the books findAll
and findRecord
response. But books have been included within the quotes response and normalizeResponse
on books didn’t take care of that.
So if I had completely understood the serializer before I started on this screencast, I would not have chosen type
as the one to change from book
to kindling
. I would’ve changed the id
or the attributes
or the relationships
, because the type
is the one place where Ember data does not have your back if it’s going to change, because as you can see, it’s failing before we even get to normalize
. It’s trying to call normalize
but it can’t find the model for kindling
. And so if you want to do this, if you want to rename a type, you’ll have to actually change it in every single normalizeResponse
, because it uses the typeClass
to find which class you’re going to call normalize
on.
So knowing that limitation of normalize
, let’s get started on what it can do. We’ll have another deviation from JSON API, in this case the id
. So instead of just being 1
, it’s quote_1
, and this affects both the main data when they’re having quotes, as well as when you include quotes in a books
API call. This will affect our app in several ways. In our quotes
directory when we click on a quote, it’ll go to the wrong route. It’ll go to quote_5
instead of 5
, and it’ll give us an error as well, and it won’t show up as an error for the user until you try to reload. And then we can see that it’s trying to call it with quote_5
instead of just 5
, and not surprisingly the server can’t find it.
And then here in our individual book show page, it just errors out and doesn’t show anything. So we’re going to use normalize
to fix both of those. So we’ll create a normalize
method on our quote serializer, and it takes a modelClass
and a resourceHash
. And let’s go ahead and call the debugger
to see what both of those look like. So our modelClass
is the quote, and we’ll see that this is the same in both because it’s running it again for each individual JSON API object and not for the response as a whole. And then the resourceHash
is just that object. So here it’s the attributes
, the id
, and the type
. And here it’ll be a little larger because it will have the relationships as well, so this is a book that it’s related to.
So how we’ll fix this is by taking the resourceHash.id
and setting it to something else. So what we set it to has to be the id
at the end, the number at the end of this. So if it’s quote_1
, we want it to be 1
. And so what we’ll do is we’ll call that id
and then we’ll just use JavaScript’s replace
method, so we’ll replace quote_
with a blank string. And so that’ll set the id
to just whatever comes... whatever’s not quote_
. Then we have to return the results from super. Now if we go here, we’ll discover that you can click here and reload without error, and we can load our books without error as well. So setting the normalize
for the quote, changing the id
in the normalize
method fixes it everywhere that there’s a quote JSON API object.
So that’s it for today’s episode. We saw what set apart normalize
method from normalizeResponse
. We saw the limits of the normalize
method as well as how it can be used usefully and efficiently for changing something like the id
. And of course, just like normalizeResponse
, there’s a set of sub-methods that do more specific things. So normalize
, it can do what all of the sub-methods can do, but the sub-methods just do them more efficiently. So here’s another way to do what we did in this episode. We’re going to go over extractId
and several other related classes in this week’s pro-episode. So I’ll see you then.
- Ember Data 2.0-Getting Started, and Basics of DS.Model
- Ember Data 2.0-Getting Data from the Server with findRecord and findAll
- Ember Data 2.0-Store Manipulation with Peek, Unload, and More
- Ember Data 2.0-Create, Save, and Destroy Records
- Ember Data 2.0-Updating Data, Tracking Changes, and Rolling Them Back
- Ember Data 2.0-Metaprogramming with DS.Model Attributes Property
- Ember Data 2.0-Model States and Flags
- Ember Data 2.0-states.js Deep Dive
- Ember Data 2.0-Relationships
- Ember Data 2.0-Metaprogramming with Relationships
- Ember Data 2.0-Overview of using Adapters and Serializers
- Ember Data 2.0-Overview of Customizing Adapters and Serializers
- Ember Data 2.0-Essential Adapter Customizations
- Ember Data 2.0-Advanced Adapter Customizations
- Ember Data 2.0-Miscellaneous Adapter Customizations
- RESTAdapter vs JSONAPIAdapter vs ActiveModelAdapter
- Introduction to Serializers
- JSON API
- Serializers-normalizeResponse
- Serializers-normalize${specific}Response
- Serializers-How are normalize and normalizeResponse different?
- Serializers-Extracting Attributes and IDs
- Serializers-Extracting Relationships
- Serializers-keyForAttribute and keyForRelationship