Build a simple caching mechanism for your AngularJS data models.
Brett: In the previous video we built an inheritance mechanism for our base class, and now we need to start adding some functionality to that class so that all of our classes inherit from it.
I'd like to remind you that if you have an app that needs to go into production today, you can Google "ngActiveResource." It's the completed resource of the base class that we're going to be building on screen here, but you can get started modeling with that today.
Assuming you want to go through and build this from scratch, let's take a look at why caching is so important in Angular, and why that's the first thing that we want to add to our base class. I just want to show you here...
This is one of the questions that I actually get asked the most about AngularJS, which is, "I have a couple of objects that are supposed to represent the exact same object. They're on multiple scopes. Why aren't they updating one another? What's going on? Am I using scope.apply incorrectly?"
No. It's not actually that you're using Angular incorrectly, but it's that the documentation doesn't show you the best way to approach this, so I want to show you here a couple of sibling controllers, so each of these sets, the first and second, third and fourth, fifth and sixth, seventh and eighth, they're each siblings of another.
We want the data on one of them to update the data on the other one, and we're going to show a couple of common ways that people try to approach creating models and see whether this works or whether it doesn't.
On our first and second controller, this is the way that the Angular docs show you to do it. They show you to create just a plain old JavaScript object and assign it to your scope here, but I'd like to note here that these, although they have the exact same information in them, are actually different objects, and this is the number one thing to take away from this video, that if these two things are different objects, they will not update one another, no matter how much you scope.apply.
They're different objects, so JavaScript doesn't know that it should be updating one or the other, but as humans, we know that this is supposed to represent the same thing, so we want to show how we can actually make that happen.
In the third and fourth controllers, we're using a mechanism that John taught in a very early video, and that's to create a provider here that returns a single object, so this is a singleton. It's always the exact same object. It has this data [indecipherable 02:13] .
The third and fourth controllers should update one another, but this isn't really useful. If we're building multiple instances of the same type, we want to be able to instantiate a bunch of different objects, so that's not going to work in production for us.
In the fifth and sixth controller, we actually create a model, and this is closer to what we would use in production here. We see we have just a basic function that's going to return a new object that has data equals cool, but the thing to notice here is that, again, these are creating different objects. If the two objects are different, they can't update one another, so this one's not going to work.
In the seventh and eighth controller, what we're actually doing is creating a constructor that uses caching, so we're going to use the primary key, which the database should send back to us, assuming we have a back-end on our app.
If we have the same primary key, we as humans know these are supposed to represent the exact same object, so this could also be something like ID equals one, and we could give this user a name, things like that, and that will start to return the same object.
This in the seventh controller will create a new one, and in the eighth controller we'll say, "Hey, this is the primary key. I already have this in my cache. Let's return that same instance," so these two should update one another. Let's take a look at what this looks like.
Remember, this is the first and second controllers. These are object literals. They're different, so they're not going to update one another. When we have the same object returned from a provider, these do work. This is what John showed us in an earlier video, remember, so we know that these two will update one another.
Now we have the same information but different objects returned from a constructor, so these guys are never going to update one another because, one more time, can't reiterate it enough, these are different objects, and now, if we using caching, these update one another. They're identical objects because we've used the same primary key to cache them, so this is why we want to add caching to our application.
There are a couple of other really important reasons we'd want to add caching, such as not making HTTP requests for resources that we already know we have, so let's move on to our next video and add caching to our base class.
Hey Tim- In terms of just straight caching (and other things), there's no reason not to use Breeze, which is a great library. In this series we're looking at building an Angular-specific library, so you don't have to worry about the digest cycle or bindings updating when you work with them--they should just work out of the box because these are issues that we have to deal with for every Angular model. There are other semantic niceties that I like from the Rails world that we'll explore. At the end of the day, my bottom line is convention over configuration; I'm looking to expose the simplest possible API that still gives users the flexibility they need (at the end of the day, though, I'm not DHH, so we'll see how all that goes :) All this with a grain of salt; we're not going into quite the complexity of an ORM in this series, but we're looking under the hood at how some of these things are designed so we can get a sense of what these libraries are concerned with (and hopefully expose some new details you might not be familiar with.
I just asked this in a tweet, but realized the comments on the video might be a better place to ask. Your ngActiveResource library looks really awesome, but I was curious why you use this over Breeze.js.