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.

Introduction to Ember Data 2.0

Subscribe to our mailing list