Refactoring mutations to enforce immutable data in Angular 2

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 5 years ago

When a Todo property updates, you still must create a new Array of Todos and assign a new reference. This lesson walks you through refactoring from the current approach to the immutable approach.

[00:00] In exactly the same way that our search pipe requires us to update the reference to a new array whenever a new item gets added -- like swim -- if I try and toggle one of these and set up a pipe that filters out any of them that are toggled, that means that I need to update the reference to a new array whenever this property changes the status of that todo model. The pipe for that would look like this, where I can just copy and paste by search pipe.

[00:33] I'll call it a started pipe. Pipes are basically just a name, so started, change this to started.

[00:41] Then instead of filtering on the title, let's filter on the status. We want to check if a status is started, so in my todo list, I'll swap out search pipe with started pipe, started pipe, started pipe, and started. Now you'll see that it shows each item that is started.

[01:05] If I try and mark these as completed, you can still see they're shown. They're not being filtered out. To make this work, we need the todo item renderer to notify the service and have the service create a new array with that todo that got updated changed.

[01:20] In the item renderer, instead of doing todo.toggle, what we're going to do is dispatch a toggle event, so we need two imports here, output and event emitter. Outputs are how you set up custom events, we'll call it toggle.

[01:36] You need to instantiate a new event emitter. Instead of todo.toggle in the click handler, we'll say toggle.emit and pass out the todo.

[01:50] This is an event emitter which is going to send out the current todo to the parent component, which is our todo list. To handle that toggle event, I'll just create some new lines here just to make it easier to read.

[02:03] We'll use the parens, just like we'd handle any sort of click event or anything. We can handle a toggle event, which we set up.

[02:10] To handle this toggle, we'll set up a handler on our todo service, say toggle todo. Then pass in the event, because in our case, the event is the todo, which is being emitted from my toggle event emitter.

[02:28] Toggle dispatches the todo, and then my todo list forwards it onto the todo service. Then in the todo service we can say, toggle todo and we can check that this is the right todo, so anytime I click here, you can see, I get the eat, sleep, and code.

[02:51] Instead of just logging this out, I can say, todo.toggle, and I need to update my array to make this all work.

[02:59] The way that we're going to construct this array is by finding the index of the toggle that got passed in, so this.todos index of todo. Let's call this I. Then use the index to grab every item before, which is this.todos.slice.

[03:18] We'll start from zero, work all the way up until we find the current todo, and then use the spread operator to take each todo and just drop them into that array.

[03:30] Then we'll drop in that current todo, which is the updated one, so this guy right here who is toggled. Then we'll finish it off using a spread version of todos, slice, and in our case, I plus one is going to give you every todo after the current todo that got passed in.

[03:50] You can think of it as we're reconstructing the same array using the items before it, the items after it, and the current item. If I click on sleep, then this is eat, and this is code, and this is sleep.

[04:04] I'll go ahead and save now. I'll toggle sleep. I'll toggle code. I'll add swim, I'll toggle eat. I'll add dance, and toggle those both away.

Andre
Andre
~ 8 years ago

this.todos = [ ...this.todos.slice(0, i), todo, ...this.todos.slice(i + 1) ];

I don't understand how the todo item being toggled is being removed when it's being added back to the array in the todoToggle function?

Andre
Andre
~ 8 years ago

Answered my own question by looking back at previous code. I had forgotten about the 'started pipe' that was created in an earlier lesson, which is filtering the list of todo items that are then outputted by the *ngFor.

Markdown supported.
Become a member to join the discussionEnroll Today