Instructor: Alright.
Let's now finish up this recipe part
by updating the servings, and the ingredient list
whenever we click the increase or decrease buttons.
And, so you're actually gonna learn something new
in this video that we haven't talked about yet.
Which is another way of implementing the event delegation
using the matches method on DOM elements.
So again, the idea is to decrease or increase
both the servings, and the ingredients here
whenever we hit these two buttons.
Okay?
So let's start with a model here.
And, I'm adding a new method here called update servings.
And, so we actually need to update servings,
and also the ingredients.
Okay.
And, we actually need also a parameter
to this method here called type.
Okay, and so that in here can pass like a string saying,
decrease, or increase in order to decide if we need to
increase the servings, or to decrease.
Okay?
So basically, if we hit the minus button, then we will
pass in decrease, and if we hit the plus button,
then we pass in increase.
Okay?
So let's create a variable called new servings.
That will be set according to the type.
Okay?
So let's use the (unintelligible) operator here.
And, say if it's thick, so it stands for decreasing.
Well, then this.servings
minus one
is
plus one. Okay?
Now, this will not update here this.servings,
it will simply then assign this value to type.
Okay?
Or, sorry it will actually just
assign the value to new servings.
Okay?
So if type is decrease, then new servings will be
this.servings minus one, and otherwise it will be
this.servings plus one.
But, it will not update right away this.servings.
So you have to take care of that later.
And, actually we can do it right now.
Okay.
But, we still need that new servings variable here
to calculate the new ingredients.
And, that's why we had to calculate it first.
So this.servings will be the new servings.
Alright.
And, now as for the ingredients,
well, we need to update all of the count numbers, right?
Because the count numbers that we have,
they're valid only for the current amount of servings.
So, we assume that we have four servings,
and that the count that we have in the recipes
are perfect for that.
So, if we then decrease or increase the servings,
then we also have to update the counts.
And, we're gonna have to do that for all of the ingredients.
So, this.ingredients, and remember
that this is an array.
And, so let's use forEach now.
And, forEach ingredient,
we will have to change the count.
So ing.count
will be, and remember that ing
is the current value forEach loop.
And, well the count will be the old count.count
times the new servings
divided by the old servings, basically.
So, this.servings.
Okay?
So, imagine that we had four, and now we have three.
So, if we add count before one,
then, well before we had four,
and now we have three quarters.
Okay?
So, that makes sense.
Now, we can make this even better,
because instead of having to repeat the ing.count here,
we can simply put the multiply here,
and then, this will mean the exact same thing.
Alright.
And, only now we can finally update the this.servings
in the object, okay?
If we had done this here immediately,
then we couldn't use it here.
Okay?
And, that's why we have to do it afterwards.
So, this updates the servings, and both the ingredients
in our data model.
So, that's the first part,
and with that, we're done.
Next up, let's go ahead to our controller here,
and implement the event handlers for the two buttons.
Okay?
And, so once more we have to use event delegation
because these buttons, they are not yet there
by the time we load the page.
So, the only thing that is there is the recipe elements.
So, all of this.
And, so that's where we will have to
attach the event lister to, and then use
the target property of the event in order to figure out
where the click actually happens.
So, just like we did before, but in
a slightly different form, as you will see in a second.
So, handling recipe
button clicks.
Okay?
So, we have our recipe control, and then let's add it here
also to the same thing.
Later, we will add in some more when tending to this.
Because, remember we also have the like button,
and the add to list button.
But, for now we're just gonna take care of the increasing
and decreasing of the servings.
So, anyway, let's now attach the event listener
to elements.recipe.
So, that's the element that's already there at load time.
And, then add event listener.
Click.
And, then we need the event, of course.
So that we can then use the target on it.
So, last time we did event handling, I showed you
the elements.closest, right?
Ah, yeah. Here it is. So here is the closest.
Now, this time around, we cannot use closest
because there is more than one thing
that we might potentially want to select, okay?
So, here in this case, we knew that we want to select
the button in line.
The problem was just that there are
some elements in there which we could also click on.
Okay?
But, right now the situation is different
because we have different elements
that we might want to click on.
We have the increase button, we have the decrease button.
We later will have the heart button,
and the add to list button.
And, so we cannot just close this because then it would be
impossible to target these different elements.
And, so instead what we're going to do, is to basically
test what was clicked, and then react accordingly.
Okay?
And, so this time around, we're gonna use
the matches method instead of closest.
Okay?
So, let's use an if statement.
And, so the event.target.matches.
And, now in here we can simply pass a css selector
just like with document.query selector, for example.
So, we can simply say button decrease,
which is the class name.
So let's take a look at that.
So, search view, and that's not the correct one.
So, yeah.
Recipe view.
So, we have here the,
where is it?
And, actually, I see
that we're missing here the class names.
Okay?
So, let's add button decrease, and button increase.
Okay?
So, the first must decrease for the minus,
and for plus it is increase.
So, what we say here, is that we want to do something
if the target matches button decrease.
Or, we can add a second selector here.
Just like we do in css.
Button decrease, and then any child.
So, that's what this asterisk here means.
So that's like the universal selector
inside of this parent element.
And, let me, not here.
And, so let me show you why that is,
because again, we might click on this element,
or on this element.
And, so like this, it will match
these two elements here as well.
Okay?
So, because again, this turns out to be true
if the target matches the button decrease,
or any child element of the button increase.
So, that's what this part here, the selector means.
Alright?
And, so now, we can then respond to this.
It is clicked.
Okay?
And, now we can go add and copy this
because it's pretty much the same for the next one.
And, I see that here there is actually a mistake.
Let's go ahead and copy this one, and here we want increase.
And, here also.
So, what do we want to happen in this case is, of course,
state the recipe.update servings.
And, we pass in decrease.
So, that's the string that we define the pass in.
Okay?
And, then the same here for increase.
Alright?
And, then just log it to the console.
So, the entire recipe.
Okay?
Just so that we can see the actual serving.
'cause right now, it's not yet updated
on the user interface, of course.
State.recipe.
Okay?
And, so yeah, let's test it out.
Oh, and something is happening.
So, you see the servings is now decreased to three.
Great.
And, now this is at one point five.
And, this one here,
yeah, this here was the original state.
And, so you see that it was two before, right?
And, so it's actually working.
Even updating here the ingredients.
So, you see one cup of mozzarella, and now,
it's just zero point 75.
And, if I decrease it even further,
then let's see what happens now.
And, indeed, it's one and zero point five.
Now, let's see what happens when I keep clicking
and the problem is that we now have negative servings.
Minus five, and here we actually have
not a number on all of these.
Okay?
So, this is something we have to fix.
And, of course, that's very easy to do.
So, we can only do this if state.recipe
dot servings is greater than one.
Only then we can decrease it more.
Okay?
And, here the plus, well there is not really a limit.
I could put a limit here as well, like,
that we cannot put it to 100 people,
but that's not really necessary.
Okay, and so now finally, let's of course update
the user interface as well.
And, So I'm gonna add a new method here.
Export and update
servings again, and let's call it
update servings and ingredients.
Okay?
And, we pass in a recipe,
and based on that, we will then update everything.
Okay?
So, again, we have to update the count,
and we have to update the servings, or the ingredients.
Okay, so it's not count, it's like the servings themselves.
So, the first one should be fairly easy.
Document.query selector.
And, once again,
I have to do query selector here because
this element is not yet there by the time we load the page.
And, so we're looking for the ingredient count.
So, where is that?
Servings, it is this weird class in here.
And, ideally, we could have some class names that are
specifically just for javascript.
Okay?
But, well, in this case I just did it like this.
So, no big deal.
It still works, obviously.
Okay, and so now, just changing the text content to
recipe.servings, and that's it.
So, this one is very simple.
And, now onto the next one.
So, basically what I'm going to do here is to select
all of the ingredient counts,
and then update them one by one.
So, let's take a look at that.
So, recipe count is their name, alright?
So, I'm gonna go ahead and copy it.
And, so, let's start by saving the selection here, actually.
So, count elements.
Okay?
So, array.from, and now we do our
document.query selector all.
From recipe count.
Okay.
And, now what do we do with this?
Well, we do a simple forEach loop.
And, now in here we actually need the element,
and also the index.
And, you will see why in a second.
So, we're gonna change the text content
of each of this element.
And, what do we change it to?
Well, first of all, we use the format count function
that we used before.
And, what we're gonna put in here
is the recipe.ingredients.
Remember that is the array.
And, now at position i.count.
Okay?
Make sense?
And, that's why we needed the i here.
Because basically, we're looping over two arrays here
at the same time, so we have the recipe.ingredient
array, and the count elements array.
So, we're using forEach.
On this one, and then also
using the current index to retrieve the value from
the ingredients array.
We could have done it the other way around,
so that forEach could be on the recipe.ingredients.
And, then we would use the index on the counter elements.
So anyway, things should now be actually working already.
So, let's wait for the reloading of it,
and let's try it out.
Well, that didn't really happen.
I guess that's because we didn't really
call this function here.
So, that's a stupid mistake.
So, recipe view.update server ingredients,
and in there we pass the recipe, so state.recipe.
And, the same, of course, also for the case that
we increase the serving.
Okay?
So, now we should be ready to rock.
So, let's try it, and here we go.
It's working.
That's fantastic.
So, we can increase it as we wish.
Now, that's try to increase it even further.
And, it stops at one, just as we defined.
Okay? So, perfect. Awesome. It's really working.
And, so with this, we actually finished this section.
Well, we're gonna add some more stuff here.
Namely, this like button.
And, this button here.
But, for now, it is really working.
And, so I hope you're proud of yourself
for making it this far into the project.
Next up, we're gonna take care of this shopping list.
So, if you still want to continue this momentum,
well, then just join me right in the next video.