It is important to have consistent data for your application to use. To achieve this, our modeling library will need to have the ability to serialize and deserialize data received into a format it understands, plain old JavaScript objects.
This lesson is part of a series on building a robust modeling layer in your AngularJS applications.
Man 1: [00:00] Hey, everyone. The next step we're going to talk about today in our modeling library is serialization and deserialization.
[00:05] Deserialization is where we're going to get a response from our API, such as this bit of XML here if we have an XML API. What we want to do is actually transform this into a JavaScript object so that we can work with it in our JavaScript application.
[00:24] Serialization is the inverse operation. We're going to have our JavaScript application. When we want to save it, we need to transform it into XML so that our API knows how to read it.
[00:34] We have these gateways that sit at the edges of our application that perform this serialization and deserialization for us. This is an important part of the modeling library's responsibilities.
[00:45] Let's take a look at how this works here. We've exposed a configuration option on our API here which allows us to configure the format of the API. We'll actually be allowed to be even more specific here and give a fully qualified mimetype. We can see the differences between giving that MIME type and just giving this basic XML in a moment.
[01:05] We just want to see what happens when we run deserialize on this bit of XML here. Let's take a look.
[01:11] What we get is a bit of JSON. It's wrapped under this post object. We get all of the attributes for the post then underneath that.
[01:20] This is a common response that we're going to get from a back end where we have an object that's wrapped under a root element.
[01:28] We also have a configuration option for this that says we want to unwrap the root element here. The difference then is we get the attributes on the model.
[01:39] This is exactly what we want. We want to, by the time we've handed this off to the application, to have just deserialized to the attributes that we're interested in for our model.
[01:51] If you're paying really close attention you'll also notice that we've transformed to author ID here from the author association that was listed. We're going to take a look in a little bit at how we do that. Just hold on to that thought for a moment.
[02:05] What actually happens when we call deserialize? Well, there's really not that much code centered around it. It all fits on the screen right now.
[02:13] We have two events that fire, one before and one after we deserialize. This allows the rest of our application to hook into events. If we wanted to, say, post...Remember we're deserializing posts so if we want to say post.before deserialize we can run a function with the callback and get the XML object here if we wanted to do something with it before deserialization at any point in the application.
[02:42] Then we deal with the case where we didn't actually get any response from the API and we sent that to an empty object just so we're always sure we have some JavaScript type thing.
[02:52] Then there are actually two methods that run to allow us to deserialize from one format into a plain JavaScript object.
[03:01] The first one that runs is the mimetype parsing option. Let's say that we've been given our XML here. This is just pseudocode, right?
[03:11] If we have a post with an ID of 1, and this is what we receive we want to first make sure we transform that into a JavaScript object. The reason that we're interested in transforming this into a JavaScript object first is so that the rest of our functions can know that they will always have a JavaScript object as input.
[03:34] It's much easier to work with than getting XML, sometimes getting JSON. We want to make sure that we always have something consistent for the rest of our application to work with. We really have this gateway set up here to make sure that nothing passes into the application unless it's a JavaScript object.
[03:53] We run that first. Then we run the unwrap root function if that happens to be set on the API. Then we run a special function that is defined on the model. It's called "parse." If there is a parse function we'll run through that. If there's no parse function, we won't bother with it.
[04:10] This parse function allows every single model to define very specific ways to deserialize data. In this case, remember we had post.author. We saw that we had transformed that author into an author ID here. This is how it happened.
[04:27] It's because we got this author object and then we saw that on our parse method. We said, "Grab the ID from that author and make that post.authorID and then delete post.author." At the end of this function we just return the post itself.
[04:43] We return that JSON object with the author ID. This allows us to both transform from the XML format and then, also, perform any little additional transformations that we want to before our application actually ends up receiving the data.
[05:01] I really want to make a big point here about deserialization happening at the edges of our application. Our application never even knows that it interacts with XML data because whenever it receives HTTP responses all of our HTTP responses are piped through this response handler.
[05:22] We don't need to worry about most of this handler here, but if we come down here if we've determined we have a successful response, we didn't get a 400 or a 500 response. We got something in the 200 range then we're going to run through the response resolver.
[05:40] The first thing that the response resolver does is call class.deserialize. It receives this response data and it runs through the deserialization method. The response that the application thinks that it receives is actually this deserialized data.
[05:59] We never have anything but plain old JavaScript objects that come into the application.
[06:06] I want to show you the same thing is true when we go ahead and save data. Whether we're sending a put or a post, we always send the instance, running it through the serialize method which we talked about being the inverse of the deserialize method.
[06:23] To show you how similar the serialize method is, it is the exact inverse of the deserialize method. The first thing that it does is run through our model specific format method. This is the inverse of our parse method. This transforms it back into something that the back end wants to see.
[06:45] Then we rewrap the root if we need to. Finally, we call mimetype.format. We see we have parsers parse data that comes in and then formaters format data that goes out to our application. Then we return the serialized data to send to the API.
[07:03] To recap what we've learned today, we've learned that deserializers transform the data that comes in from out back end responses into JSON and that serializers transform our JSON objects into the back end format that our back end expects.
[07:20] These occur at the edges of our application so that the rest of our modeling library doesn't even need to know that they occur. We can swap in and out model formats as we please without changing the way that rest of our application functions.