This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Fix Shared Mutable State" Lesson
[00:00:00]
>> Lukas Ruebbelke: Now we need to fix this because we still have shared mutable state. And so I was talking about this on the break, that,
>> Lukas Ruebbelke: Shared state is totally fine, we have to share state. I mean, when you cross down from the server and you're getting state, you're sharing it.
[00:00:20] Mutable state is totally fine, eventually you're going to have to mutate state. Sure, mutable state is the devil's playground, and this is where things go to cause mischief in your application. So if you want to share state,
>> Lukas Ruebbelke: Make it immutable. But if you want to mutate state, then isolate it so it's no longer shared.
[00:00:51] And so how we do this is I'm going to replace project with we'll go with currentProject.
>> Lukas Ruebbelke: We'll save this, so now it's currentProject. And it's saying,
>> Lukas Ruebbelke: That doesn't exist yet.
>> Lukas Ruebbelke: But in our component, we're going to make one small change. We're gonna go here, currentProject, and I could even,
[00:01:33]
>> Lukas Ruebbelke: Type this.
>> Lukas Ruebbelke: There we go.
>> Lukas Ruebbelke: And let me move this down to the bottom. So does anybody know what a setter is?
>> Lukas Ruebbelke: That setter or a getter, is you can either get a property or set a property. But it's actually tucked behind that is a method.
[00:01:58] And so now what we can do is go set value. And from here, say this.currentProject =.
>> Lukas Ruebbelke: Here it is, we're hanging in the balance. How do we keep this from being shared mutable state?
>> Speaker 2: Copy by value and not by reference, right?
>> Lukas Ruebbelke: Right, so you would make a copy of it.
[00:02:31] So you create a local copy. And so what we're doing here is using Object.assign is that we're saying take,
>> Lukas Ruebbelke: The value that we passed in, and assign all innumerable properties to this empty object. Now you're no longer dealing with application state, but you're dealing with presentation state.
[00:03:01] So you're taking something that's shared across the application and we're saying I want to make a copy of this. Now this is a fairly simple object. So if you're doing deeply nested objects that reference other objects, that you could run into problems. And you may need to use something like Ramda or whatever.
[00:03:20] But for most basic single depth objects, this is not a problem. So using Object.assign is it takes this Object here, or you could actually do multiple Objects. Let's do all innumerable properties and then assigned it to this Object here. And so now when we save this, anytime project is updated via the binding, is it's now creating a copy and storing it as a local property.
[00:03:55] And so now whatever happens in this form is no longer,
>> Lukas Ruebbelke: Shared. It's certainly mutable, but it's not shared. Let me just double check, make sure. Yes, currentProject exist, come on. Let's go back here, make sure that nothing is breaking. Select this, now keep an eye over here.
[00:04:29]
>> Lukas Ruebbelke: So we fixed it here but it's still happening over here. So what I would do in this case,
>> Lukas Ruebbelke: Is I'll create.
>> Lukas Ruebbelke: We'll go with, I think its Title, originalTitle, declare a new value here. And I'll just say if there is a value then let's set this originalTitle to value.title.
[00:05:03] And so now we're just creating, again, taking this and making it presentation state. So now, even within the component, extending this concept, is we're saying because we're mutating this. And we could mutate the title because it's shared in two places. And so these are kinda these little things that I want us to start queuing on as we're building applications that, hold on.
[00:05:28] currentProject.title is here, but it's also over here. And because this is in ngModel, this is mutable.
>> Lukas Ruebbelke: So what we'll do is we say okay, if you're gonna be mutable, then you can't share. Remove it. And so we'll go originalTitle, like so, save it.
>> Lukas Ruebbelke: And now when I go here,
[00:06:07]
>> Lukas Ruebbelke: It's isolated from this, more importantly that it's isolated from this as well. Is if I were to cover to this up, so let me just inspect. And we went to here and let's just say I deleted this element.
>> Lukas Ruebbelke: And I looked at this, I'd have no idea what the original object was.
[00:06:30] What am I dealing with? I don't know. But by now creating a visual cue, so this is just a UX thing, back to this, I could completely delete this and I still know I'm working. And I have a visual connection back to here. Now what we can do is, when this was mutable, and I went here and I started changing something, how would I undo that?
[00:06:56] What if I'm like just kidding? I don't wanna make this change. Well, you've already mutated the object. I mean, it's kind of like peeing in the bath water. You just cannot do that. Whereas now you're creating separation. And if you want to discard it, you would just say not a problem.
[00:07:17] I'm just going to cancel. And you know what happens? You just throw that object away. You don't need it. And so we'll go here,
>> Lukas Ruebbelke: emit.
>> Speaker 3: [INAUDIBLE]
>> Lukas Ruebbelke: Did I not change that back?
>> Group: [LAUGH]
>> Lukas Ruebbelke: I was trying to be so helpful, my goodness. Don't ever have four-year-olds and seven-year-olds because you start talking like that and you forget to revert back.
[00:07:46] So, cancelled.emit.
>> Lukas Ruebbelke: I don't really, what I could do is just for the sake of,
>> Lukas Ruebbelke: Let's say you wanted to actually restore, I don't know why I'm doing percentComplete, let's go currentProject. You want it to you exited out of this form. So if you've ever done long form insurance applications, and somebody's like I wanna cancel, or I need to go do something.
[00:08:14] And they need to come back, you wanna restore state. It probably would not hurt to just grab this currentProject and store it off somewhere. So just as a matter of course, I typically would send that up to the parent component. It can do whatever it wants. But this child component doesn't have to worry about it.
[00:08:31] Are you caching, are you not? Are you gonna restore it, who cares? The child component doesn't care. And then onto the form, let's go submit.
>> Lukas Ruebbelke: And saved.emit(selected, not, currentProject. At least it's not wahoo.