Ember 2.x Ember 2.x

Exercise 7 Solution, Part 1


This course has been updated! We now recommend you take the Ember Octane Fundamentals course.

Check out a free preview of the full Ember 2.x course:
The "Exercise 7 Solution, Part 1" Lesson is part of the full, Ember 2.x course featured in this preview video. Here's what you'd learn in this lesson:

Mike walks through the solution to Exercise 7. He starts by adding the “isFavorited” macro and adds the code for favoriting an organization.

Get Unlimited Access Now

Transcript from the "Exercise 7 Solution, Part 1" Lesson

>> [MUSIC]

>> Mike North: Just to restate the problem. So we're trying to add a computed property to our github-org component so that we have something to bind to, a Boolean value to bind to, that will flip back and forth between true and false depending on whether that github-org is in our list of favorites.

[00:00:26] And we wanna do so in a generic way using a computed property macro, because this is a generally useful thing, to know the presence or absence of something in an array. It could foreseeably be of importance for later steps in our app. And so let's get started.
>> Mike North: So I'm gonna get back to reasonable screen sizes here.

>> Mike North: Close some stuff out.
>> Mike North: Great, so we're gonna begin with Ember CLI.
>> Mike North: And just making sure I'm at, yep, we're starting from the end of our components exercise. So this is push to master, you should be starting from the exercise six commit. So we're going to generate a util, which is just a simple function, in this case that function will return a computed property, is in array.

>> Mike North: So it's going to generate the module itself, the util, which we're gonna consume in our app. And it's also gonna generate a unit test and we're gonna get to testing very soon. And I just want to show,
>> Mike North: In that test, especially if you get confused about importing and where imports are, it's worth noting that your test needs to be able to import this in order to use it.

[00:02:15] You can see that we can use a relative path here or we could just do something like that. So the pro tip here is, if you've generated code and you can't find your module or something, look at the automatically generated test and that'll give you a clue. So we're gonna copy that, and we're gonna go to our github-org Ember Component, and we'll import it there.

[00:02:45] And right now, isInArray doesn't do much but I'm gonna set it up, get it ready to go, isFavorited: isInArray. And I'm gonna make the first argument we pass in here, it'll be the property name of the thing we're favoriting. And then the second argument is going to be the property name of the list, which we don't have right now.

[00:03:13] In order to get the list, we have to get it from our service, and the way we make our service available to this component is via inject. Don't need to specify the name. It knows favorites is the name of the service we wish to have by way of the property key here.

[00:03:37] And we're gonna say favorites.items, I think we called it, add my comma. And I haven't implemented as an array, but it's not complaining, and the reason is computer properties are evaluated lazily. Nothing's attempting to call this thing yet, so it doesn't know that it's broken.
>> Mike North: isInArray, so we're gonna go to our utils folder here.

[00:04:13] And I have to import Ember.
>> Mike North: And I'm going to destructure so I can just say computed, keep it clean.
>> Mike North: And just keep myself organized here, the first argument again is item and the second argument is list. And actually, just to be explicit, I'm gonna call it list and itemKey, because remember they're property keys.

[00:04:48] They're not the list and the items themselves. So the first thing I'm gonna do is I'm going to declare the itemKey as a dependency of my computed property. So if the item changes for this component, we need to reestablish whether this is favorited or not. We'll have to clear the cache for this property and recalculate it.

[00:05:12] And then the other thing I'm going to do is declare a dependency on the list. In this case I only really care about the length of the list. And I suppose we could get into a situation where we're changing other things that potentially could make this computer property untrue, but I'm not gonna worry about that.

[00:05:29] I just care about additions and removals from this list cuz I'm managing it. I know what I'm doing. I know there's limited things I can expect to happen to this list. So the way I'm gonna write this is listKey, which is gonna be like favorites.items, and I'm going to add square brackets.

[00:05:55] Who remembers what square brackets mean?
>> Mike North: And the other way of having a dependency?
>> Speaker 2: At each.
>> Mike North: At each, great. And then the next thing is function, which is Do the computation.
>> Mike North: And I'm just gonna, cuz I know I'll need it.
>> Mike North: I don't know if you guys discovered this while playing around, but within the body of this function, this is the object that your computed property lives on.

[00:06:41] So in this particular case, it's gonna be the component. For that reason, do not make this an arrow function. Arrow functions are not just shorthand for the word function. They also bind. So be careful. Be careful about that. I use arrow functions in a lot of places, and this is one place where you have to still use ES5 function syntax.

>> Mike North: And I've made a mistake here, itemKey, listKey. And we're gonna see how things look. I don't expect we're gonna trigger that yet cuz we haven't used it yet, but I'm gonna go to my github-org.hbs. And here I'm going to say,
>> Mike North: if isFavorited 'Favorite' otherwise 'Unfavorite'.
>> Mike North: And now we're actually triggering the calculation here.

[00:08:03] And I'm just going to check out what I've got here to make sure I'm in a good state. So I've got two things I'm interested in, item and list. Item, looks good. That looks like our repo. List, it's an empty array. Probably also good, right? So if I recall what we were adding to our list here was just the IDs.

[00:08:33] I'm gonna double check here. No, it looks like we were adding the objects themselves, cuz we had to map to ID when we were printing out our string. So I'm gonna add the object itself or I'm gonna check for the presence of the object itself in this array.

[00:08:51] So here I'll go return list.indexOf(item). So if it is in the array, this will be greater than or equal to 0.
>> Mike North: And refresh. [NOISE] I'm gonna put a debugger here and try again.
>> Mike North: I think I know what my problem is. isFavorited, so it is in the array.

>> Mike North: Okay.
>> Mike North: Flipped the inequality here. So unless it's favorited already, we're gonna have the word favorite on the screen.
>> Mike North: Awesome, let's see if it works.
>> Mike North: Sweet! So now we're actually displaying the favoriting and unfavoriting.