Check out a free preview of the full Building Awesomer Apps with Angular course:
The "Challenge 9: Solution" Lesson is part of the full, Building Awesomer Apps with Angular course featured in this preview video. Here's what you'd learn in this lesson:

Lukas walks through the solution for Challenge 9. Lukas takes questions from students.

Get Unlimited Access Now

Transcript from the "Challenge 9: Solution" Lesson

[00:00:00]
>> Lukas Ruebbelke: Let's go through this challenge real quick. But for the sake of time, I'm going to do a bit of just copy and pasting, because it is quite a bit of repetitious.
>> Lukas Ruebbelke: Work. So I'm just going to copy this and we'll just go here.
>> Lukas Ruebbelke: Oops.
>> Lukas Ruebbelke: Now what's interesting about this is, quite frankly, the only thing that changes is the parameter.

[00:00:45]
>> Lukas Ruebbelke: So we'll just go here, let's just replace this.
>> Lukas Ruebbelke: So update these primers here.
>> Lukas Ruebbelke: I'm not for sure.
>> Lukas Ruebbelke: You know what? I know how to solve this problem, because I just ran into it.
>> Lukas Ruebbelke: Make sure that you have imported headers, or you will run into some problems.

[00:01:36] And from here's, let's go into our widgets component.
>> Lukas Ruebbelke: And let's kind of fill this out. So.
>> Lukas Ruebbelke: When we call.
>> Lukas Ruebbelke: I'm gonna kinda change the order of this around a bit.
>> Lukas Ruebbelke: We're going to say, if widget doesn't have an id, then let's call create widget.

[00:02:19]
>> Lukas Ruebbelke: And just pass it through.
>> Lukas Ruebbelke: If it does have an idea, we'll call updateWidget on past history.
>> Lukas Ruebbelke: And then, we'll do create widget.
>> Lukas Ruebbelke: So again, because we're doing small fine grade functions, I would say that the level of complexity on the JavaScript itself is probably a three out of ten.

[00:03:04] And so there's a lot of kind of these really simple functions that we're putting together, to build a master detailed view that pretty much can do almost everything else. So any line of business have is generally a variation of this. So from here, we'll just go this.widgetService.
>> Lukas Ruebbelke: And we'll call create.

[00:03:31] And we just pass send.
>> Lukas Ruebbelke: Then we'll go to here.
>> Lukas Ruebbelke: That's subscribe.
>> Lukas Ruebbelke: This is going to take a result which we're not going to use, because instead what we're going to do is.
>> Lukas Ruebbelke: Just rehydrated it and reset the currently selected widget. I'm going to copy this, cuz I'm going to need it again in just a second.

[00:04:03] So, update widget, this.
>> Lukas Ruebbelke: widgetService.update, pass the (widget) in.
>> Lukas Ruebbelke: .subscribe.
>> Lukas Ruebbelke: And actually you just drop this in, this is the same. And for delete.
>> Lukas Ruebbelke: Let's go ahead and check this as well. So widget.Service.
>> Lukas Ruebbelke: delete.
>> Lukas Ruebbelke: (widget).
>> Lukas Ruebbelke: And well go like this.
>> Lukas Ruebbelke: This trailing whitespace.

[00:04:56]
>> Lukas Ruebbelke: I feel like morally responsible because it's in the TSLint that I should like leave it there, I really, like there's like a really good reason that I just don't know about. And, create, create, create, create.
>> Lukas Ruebbelke: All right, I think this.
>> Lukas Ruebbelke: I have a good feeling about this.

[00:05:21] Let's try it out.
>> Lukas Ruebbelke: So it showed up here.
>> Lukas Ruebbelke: Let's check our actual JSON and see if it actually got wrote to it.
>> Lukas Ruebbelke: Yeah. Let's go back here. Let's select it.
>> Lukas Ruebbelke: Update it. I'm pretty excited about this.
>> Lukas Ruebbelke: So, it's saved. Obviously, it can read and then we'll go here.

[00:06:08] And.
>> Lukas Ruebbelke: It deleted it, let's see if it, boom, done. Create, read, update, delete.
>> Lukas Ruebbelke: And you can see it reflected in db.json.
>> Lukas Ruebbelke: Now, one thing you could do. This is just me musing out loud, as I'm kind of typing these things over and over is, you know it's like these three methods currently are identical.

[00:06:49] Except for this one thing. And so you could almost do something like action(widget, or action) let's do something like execute
>> Lukas Ruebbelke: And.
>> Lukas Ruebbelke: Then use something like this.widgetService[action](widget).
>> Lukas Ruebbelke: This is all hypothetical. Till I try it. I think I will. All right, let's see what happens just for fun.

[00:07:44]
>> Lukas Ruebbelke: Create.
>> Lukas Ruebbelke: See what happens.
>> Lukas Ruebbelke: That's pretty cool. So, one of the things that I do wrestle with, especially as an instructor, is sometimes you can get so clever that your true intention is kind of obscured in your cleverness. And I think writing code that's easy to read.

[00:08:40] That communicates intent is way, way, way, way, way better in being clever and cute. So to that end, because JavaScript is this really amazing dynamic language, you can do things like, where that I even put in? I'm looking right at it, like this and I'm dynamically calling a method on the fly by passing in the action that I actually wanna do.

[00:09:07] But, if somebody looked at this and they're like.
>> Lukas Ruebbelke: There's gonna be this second of well, what is action? What is it? What's happening here, as opposed to somebody looks at widget.create. Just immediately, they're gonna know what it is. And so this is why even I will sometimes favor verbosity.

[00:09:30] And as you type things out, because it's 2017, our computers are super, super fast. And, we're not actually counting but, it's like we have managed garbage collection, things like that. So, I would much rather, in most cases, see widgetService.create. You immediately know what that does. As opposed to, widgetService, like, action.

[00:09:55] Because it's like well, I think I know what that does. It's even hard, because I know what it does cuz I wrote it. But, it would be interesting to pull some program out of the hall and be like hey, what do you think this does? Three, two, one, go.

[00:10:09] And the first question they're gonna ask is like, what is action? Or they're gonna have some prior knowledge to it. So, just something to consider.
>> Speaker 2: In case of nested objects, like employee address. So an employee has multiple address. So you would have, would he have a single service and you do the mapping and all of that object handling on the server side?

[00:10:37] or you do it in the component and then pass?
>> Lukas Ruebbelke: So-
>> Speaker 2: Where does that mapping logic set? Does it set in the component or the service?
>> Lukas Ruebbelke: I would definitely not do it in the component. So the question is, if you have a complex data object that is it has nested objects within itself.

[00:11:02] And, where do you map that together? And the answer to that is, certainly not in the component. A component should get a data structure, and immediately be able to render it. Because to map those together, that is business logic. If there's someone saying like, because I understand the business model I know that this, like you know, a user has a policy but they also have this other thing over here.

[00:11:29] So, I would do that definitely in a server, or a service rather. I might have like a helper function that does just that mapping. So I'm a huge fan of having classes and services do one thing. So I might have, depending on the complexity of the logic, I might have a single service considered lightweight handle that mapping.

[00:11:52] Now with that said, I would do this in Redux, and I would do it one of two ways, using observable.combinelatest. so it takes basically multiple data structures, and when either one of them updates you then can, basically it's computed data, you can basically re-compute the data. And then expose it to the rest of your app via an observable.

[00:12:14] Or, I would use reselect, which is, it's actually a reactant that you can use in NGRX. And it does the same exact thing. It's when you take multiple data structures and you just combine them together, using a comparator function.
>> Lukas Ruebbelke: And so these higher order functions, first of all with JavaScript using map find.

[00:12:38] Filter these things. Like those are amazing. But then you have those as well with observables. And you can kinda do a lot of the same things.