Reactive Angular with NgRx Effects: Data Persistence
Transcript from the "Effects: Data Persistence" Lesson
>> Lukas Ruebbelke: I will explain why we are using the state of persistence piece in a moment. So, kind of the standard shape for this, is this is a generic, standard out of the box how you would handle an effect. Is that we're listening to our actions and, in comes a type and then from here we're doing some asynchronous thing.
[00:00:31] And, then when it's complete then we are returning an action, and so this would be a very straight forward to use and we could use this. And I would say if you're not doing any kind of remote HTTP calling, totally fine. You could use this form right here, but the problem is that well, HTTP calls, asynchronous HTTP calls.
[00:01:01] And coordinating that can be really tricky especially when, what if you have more than one call? How do you coordinate that, how do you synchronize that? And if you make a change, do you allow your front end to update then update it in the back end and then just hope it works, and if it doesn't you roll it back?
[00:01:22] Or do you wait for the server to update and then you update your front end? As well is you'll notice in here one other piece is that the handling of, the error if something goes wrong is inside the post here as we make this. Whereas If we go to our effects file that by using data persistence to kind of wrap the sequence.
[00:01:54] That it's going to provide an extra layer of protection for just a straight fetch, so there's some utilities and some guards built in there. But we can also determine, in the case of like we're going to create something or modify something in the server, that we can either do it as a pessimistic update.
[00:02:11] In other words, wait for the server to complete before dispatching this into the reducer. Or you can do it optimistically and say go ahead and pass on the data structure into the reducer. And then if something goes wrong then we'll let you know so that you can undo it.
[00:02:26] So, there are very good reasons to use one or the other. The other piece here is that I find that this is a little bit easier to read. By having a clear, this is my run block, this is my error block. And so this just a slight variation on effects but especially when you're doing server communication, this is I think a really good utility.
[00:02:50] But it would be very easy to essentially do it through as well. So,
>> Lukas Ruebbelke: Go Projects, Add Project, and so let's do a run block here. So it takes an action, which is going to be LoadProjects. And it takes stay, so this is another thing that if you haven't you will run into this of well, I need to make some kind of decision based on something else in the state.
[00:03:25] And so getting that into your effect can sometimes be tricky whereas this provides this for you. What is this angry about?
>> Lukas Ruebbelke: All right, now this is where the asynchronous part comes in. So from here we're just going to return this projectsService.all,
>> Lukas Ruebbelke: pipe,
>> Lukas Ruebbelke: (map).
>> Lukas Ruebbelke: I think I'm getting little bit parentheses heavy here.
[00:04:19] So we are going to get our result, which is going to be an array of projects, and then from here, what do we do? So we have just made some asynchronous call, something has happened. And now we get our collection back, what do we do? Well, we would then want to put it into the reducer, and so we'll go new ProjectsLoaded and pass in the result.
>> Lukas Ruebbelke: I could probably even move this up here. Now that I've kind of broken this out and I know where I'm at, here we go.
>> Lukas Ruebbelke: So, how this works is we're creating a load project effect that is listening for little projects. From there it's going to run this code here.
[00:05:26] And in this case we're saying I want to return the result of calling projectsService.all.
>> Lukas Ruebbelke: But I want to not necessarily return this but instead we're going to map it to a new action object. So our trigger object is here. This is our command action, go do this thing.
[00:05:57] And then down here, this is our completed action. So,
>> Lukas Ruebbelke: With that said we need to update our reducer not to listen to LoadProjects but ProjectsLoaded, does that make sense? So what we're doing is instead of going straight to the reducer is we're creating middleware or something in the middle.
[00:06:25] That takes an incoming object, it does something, and then puts something else out.
>> Lukas Ruebbelke: And then from here let me just do one more.
>> Lukas Ruebbelke: How much of this did I build out?
>> Lukas Ruebbelke: Let me do the entire run block and then we'll just fix it.
>> Lukas Ruebbelke: All right, in this case, AddProject, here, AddProject.
[00:07:05] So, this is the command, then we're going to go create, create, all right?
>> Lukas Ruebbelke: So, we'll copy the run block one more time, sad I lost it, when it asked me to close. AddProject,
>> Lukas Ruebbelke: Instead we're gonna go create and we're going to pass in the action.payload.
>> Lukas Ruebbelke: And then we're going to go ProjectAdded.
>> Lukas Ruebbelke: And this is not an array of projects but this is a single project. Now same thing here, we go back into the reducer, it's no longer addProject but ProjectAdded.
>> Lukas Ruebbelke: Make sense? Now last but not least, the one thing that you absolutely must do or it will not work.
>> Lukas Ruebbelke: This is kind of the equivalent of, I forgot to import the right thing. Is in order for this to get registered in your application, you need to add this into your effects module for root, drop this in here. And so now It's registering this two listen for all the events.
[00:08:57] If not it just simply would not be at the middle, it would be somewhere else. And so then if we go into our projects component,
>> Lukas Ruebbelke: So even here it's like I don't know, something's not right here. Well, very astute, so, this loadProjects. The difference is this is where we're going wrong.
[00:09:18] This no longer takes a payload cuz we're just using this as a trigger. Now, I addProject on the other hand and this is still correct but instead of going straight to the reducer, that in the effect,
>> Lukas Ruebbelke: It's going to, the effect then going to call the service, and when that's completed it's going to dispatch a new action object with the result.