Reactive Angular with NgRx Entities Using NgRx entity
Transcript from the "Entities Using NgRx entity" Lesson
>> Lukas Ruebbelke: One of the deals or one of issues that we deal with, when we start to deal with large collections, or we start to do data manipulation or we need to more importantly get data out of that collection, is having an efficient way to traverse that collection and find out what you're looking for.
[00:00:19] So a very common pattern for that is to convert a collection. So when I say collection, I'm talking about an array, into a key-value store. And so what you'll do is you'll take an ID of the object, and that'll be the key or a property on the object.
[00:00:39] And then you store for the value the object itself. And so what this does is when you need to go find a specific entity or specific item in a collection, you no longer have to iterate over it, you can just say, here's my key, and it can go straight to it.
[00:00:54] And so it's automatic lookup. It's also because our entities are normalized that if there is a referential relationship between these entities, that you connect them via an ID, so that you only have that object stored in one place. And if you need to look it up, then you have that ID that you can then look it up.
[00:01:20] So just think of basically classic database design where I have a key, or I have this thing, and it has a foreign key, which then is over here and then you go look that up. So, right now we're dealing with just a regular collection of projects. But what we want to do, is we want to convert that into a key-value store and then work with our projects in that manner.
[00:01:47] So you could do this by hand, and I have done this, where if something comes in, you split it out, and now you have this key-value store that you're doing this.
>> Lukas Ruebbelke: I would say not too long ago that the NgRx team, they were doing the same thing but they basically abstracted that out and created NgRx entity.
[00:02:05] So, this is a library that's designed to help you work with collections. And so, quickly and efficiently look things up, manipulate the collections as well as it produces some selectors for you to pull certain things off. So, they've just taken a lot of really common things and streamlined it.
[00:02:23] So, we are going to, in this module, introduce NgRx entity. And in order for this to work, what is going to happen, is we're going to have to redefine the shape of our state. Because we're now going to kind of defer to entity and say, all right, you control the shape, and then we're going to give you the additional properties, so what we're doing here is going to change.
[00:02:55] So I'm going to leave them together, so I'll leave the initial project state up then I'll do kind of the comparable version with ngrx entity. And then you can see them kind of side by side. So now what we're going to do is export interface ProjectsState and this extends EntityState, which then takes a Project.
[00:03:25] So it's saying, what is kind of the base entity that I'm working with, or the type.
>> Lukas Ruebbelke: And if we click in here, I think this has,
>> Lukas Ruebbelke: Ids and entities, so this is a very simple correction here. And then on top of that, then we will provide our custom properties.
[00:03:50] So in this case, this is outside of ids and entities and so we do wanna keep track of these selectedProjectId, all right? And so now, obviously, initialState is not entirely correct, but before we define initialState, we need to define an entity adapter. And so I'm going to introduce one additional step in here.
>> Lukas Ruebbelke: And then from here, we're going to export,
>> Lukas Ruebbelke: Adapter, and so this is an EntityAdapter which takes, again, a Project type. And we're just going to call it createEntityAdapter.
>> Lukas Ruebbelke: Project.
>> Lukas Ruebbelke: And then it's just a method here.
>> Lukas Ruebbelke: Let me make sure that imported correctly. Yep, okay, so we've now created the adapter.
[00:05:04] And now that the adapter is in place, we can use this to define initial state. So we're going to go export const initialState. It's still going to be ProjectState. The difference is that we're going to say adapter.getInitialState and then we're going to pass in an object with our additional initial state that we wanna use.
>> Lukas Ruebbelke: Which is going to be null, okay? But now that we've done this,
>> Lukas Ruebbelke: We can go here, so this will actually stay the same but if we go into addProject,
>> Lukas Ruebbelke: updateProject, and deleteProject, we can replace these with calls directly to our adapter. So, adapter addOne.
>> Lukas Ruebbelke: action.payload, state.
[00:06:20] So, it's essentially doing what I was doing in the helper method but with the ID and entity, so with a new shape, but it's taking care of that for us. Then if we go here, return adapter.updateOne,
>> Lukas Ruebbelke: State, and if you can imagine what's gonna happen next?
>> Lukas Ruebbelke: Adapter,
>> Lukas Ruebbelke: Is it removeOne? Yeah, removeOne.
>> Lukas Ruebbelke: Yes.
>> Speaker 2: So I'm assuming that the immutability of the objects are handled by the adapter?
>> Lukas Ruebbelke: Yes, that's correct. Yes, that would totally ruin our street cred if you pop this up and like, what? Array.push, my goodness, they're far too good for that.
[00:07:31] So, one thing I need to do here, I have in my notes is because,
>> Lukas Ruebbelke: We have changed the shape of this, we're going to say take and give us a new object, just take the state. And we're just going to say I want to update this one id here to action.payload.