-: And to finish the shopping list part of the app
let's now build the controller.
So we can close up this file here
and go back to our index dot JS controller file.
So where do we actually want to add the event listener?
And we have to do it right here in this event listener
that listens to events on the recipe object.
Okay, let's take a look at that.
So it's recipe view, so you already have
two event listeners on here. Right?
So for the plus and the minus button,
so the button decrease and increase,
and so now we need to add an event listener
for the button to add all the ingredients
to the list. Okay? And that button is down here,
so it's this one, the recipe button.
And actually, we see that we have the recipe button
also down here, okay, so let's
add another class to this one here.
So that's the recipe button.
Add. And so this will be the class for the button
that adds all the ingredients to the list, okay?
So going back to this event listener here,
we already set this one up to handle
all events that happen inside of the recipe object, right?
And you need to do it, because we need
the event delegation, because all of these elements
that we're trying to select here, they're not yet
all done by the time that you load up the page, right?
And so we need to do it this way.
So else if, and we're going to do it
in the exact same way as before.
So we're going to test if the elements
that the target had matches the string
that we're looking for. Okay?
So this one here, or any of the child elements,
so just like before.
And so that's the CSS selector for all of
the child elements of this element, the recipe button.
Okay and again, that's because the click might actually
not happen right on the spot in the element
but inside of the SVG or even this use element
or also the span element. So it can happen
on all of these, but you really want it captured
on this button itself, right?
So, what do we want to happen
when the target matches this button here?
Well, we are gonna call our controllers function.
So the fun stuff we're gonna create next.
And so that's it, so we have a recipe controller,
we have the search controller, and now we're also
going to have a list controller.
Recipe, and I'm going to put this one here.
So the list controller.
So just like before, let's add the steps
that you gotta take here in the controller.
So first off, create a new list
if there is none yet.
Right? Because imagine that we add the ingredients
to a list and open up another recipe
and then we add those ingredients as well.
So in that case, we don't want to create a new list,
of course, because we already have one, okay?
Everything I see already started implementing this okay?
So if there is not state dot list,
well then, state dot list will be a new list.
And that's it. Remember, we don't pass anything
into the list because it's empty and we don't
need to pass anything in there. We just wanted
to basically initialize the element with an empty object.
Okay, next up, what are we going to do?
Well, what you want to do is add each ingredient
to the list. Right? So where are our ingredients?
Well, they're at state dot recipe dot ingredients.
And remember that this one is an array
and so that seems to loop over
this array and then for each element
in the ingredients, we're going to add a new element
to our list, okay? So it's as simple as that.
So, for each...
(keyboard clicking)
So what are we going to do here?
We will do state dot list which is the element
that you just created up here
and now we can call add item on it, right?
So that's the data model we just defined a few lessons ago.
So we have our add item method here to which we add
the count, the unit, and the ingredients, okay?
And so let's pass all of that data into the sentence.
So we have el dot count, we have el dot unit,
and we have el dot ingredient, right?
And that's because el is currently one element
of the ingredients. And all of the ingredients
have of course, a count, a unit, and an ingredient.
And now let's take a look again at this function,
our add item function, because it will actually
immediately return this item to us, okay?
And so that's great because we can now take that
so let's save it to this variable.
And let's add this item right away to the user interface.
And I think we hadn't yet imported.
Now that's right. So recipe view,
and this one is called the list view.
So we have, and where is it?
So we have list view, dot render item
and then we just pass in the item.
So you remember, it is... we don't need this one anymore.
So we have our render item function here
which receives an item, so we just passed there
and then it reads all of the data that it needs.
And basically prints it to the user interface.
Okay, so add each ingredient to the list
and user interface. And that should actually be it
for this step. So lets now finally test it out.
You can actually test it with this here.
So add to shopping list. Whoa!
And here they are! So it's really working already.
That's awesome. So it basically loops
through all of these ingredients here
and then put each of them here in the list, okay?
And so we already have this loop here,
so we have this for each loop here,
and that's why we didn't need to include a method here
in the list view that loops over all the items.
So we did that in the search view, so we had render results
and then we looped over all of these results
and rendered them one by one. But in this case,
that's not necessary because we already have this loop here
and so it's easier to just pass this one simple function
that will then render them one by one.
Okay. For this part, it's working as of now.
And now the next thing is to actually add an event listener
to this button here, okay? And also to delete basically,
to these buttons here. So they can both delete
this entire item and also update the value
in our model whenever we change the value like this.
So that implements that, and once again, we are going
to need event delegation, right, because all of
these items are not yet there by the time we load the page.
So let's do that right after here.
(keyboard clicking)
So handle, delete, and update list item event.
So where do we want to cache these events?
Well they are on elements dot shopping, right?
So add event listener, click,
and we of course need the event.
The first thing that we're gonna have to do
is to try and read the ID of the element that we clicked on.
Okay, so basically we are trying to retrieve this ID here.
So based on the data item ID. And so,
how are we going to do that? The next few we already used
and it's quite simple. So let's say const ID
is E dot target, and now we're gonna use a method
that we used before. Can you guess which method
we will need to reuse here? Well,
it's the closest method, okay?
And that's because we need to specifically find the element
which contains our ID that we want to read.
And so we need to specifically find an element
with a shopping item class on it
close to where the click happened.
So, closest shopping item is what you're looking for.
And then just as before we can use dataset,
and then the name that we gave it.
So we gave it the item ID.
Right? So we called it item ID,
and that's why we said data dash item ID,
so that's how it will look with dataset.
And just like that, we already have our ID.
So wherever we click on the user interface now,
Now it's gonna really, but wherever we click,
no matter if we click here on this tag,
on this button, on the number,
or wherever we want really, it will always go to
the closest shopping item, and then read the ID from that.
So once again, closest is a really powerful method,
it's really really helpful. Okay. So next up,
we want to handle the delete event,
or the delete button, really. So we say if
E dot target dot matches, and so this time
we're going to use matches because that's
going to return a true or false value.
So if we're trying to test here if our target
matches the shopping delete class.
And once more, let me show that to you.
And so it's this here. So shopping delete is the class
of this button and so we will have to test
if this is the one that we clicked on, basically.
So shopping delete, or again, any of it's child elements.
So that's always the same logic.
And so if this is the case, we will want
to delete it from both the state and the user interface.
(keyboard clicking)
So very simple. State dot list dot delete item.
And of course, we pass in the ID, so the one
that we already read here in the previous step.
And then finally, list view dot delete item as well.
And again we pass in the ID, and that's it.
Now the test is a bit better, let's actually make
all of this window here, or all of this state here,
so let's make all of the state available to us
in the global window object for testing purposes.
And so now we will be able to see if it actually
deleted our item from the state. So from
the underlying data as well as from the user interface.
So let's use another recipe with just maybe a bit shorter,
with not that many ingredients.
This is better here, so this only has six.
And so here are our six ingredients.
So let's now click on this and see what happens.
Oh, we have an error. And this one is happening
in the list view, so let's take a look
at that method here. And so it's probably this part here.
So probably, it didn't correctly select
this element that we were looking for,
and then so this part here doesn't work correctly.
So first of all, let's actually pass a different item
and so basically, we only do this here
if there is an item so that it doesn't throw that error.
But now we also have to find out what's going on here,
and I can already see the problem, which is
that here is state, where it should be data of course.
So let's try that one again now.
Now let's delete the salt, and it's gone.
And now just to confirm it is also not from a state
let's take a look at it, at the recipe and the list,
of course not the search,
because we didn't search for anything.
And so let's take a look now at the list,
and indeed we only have five elements
and the salt is not in there. So it actually worked.
Alright, and now only one more thing with this
to update this data here, okay?
So let's now quickly take care of data flaw.
So back here inside of this event listener,
we can simply add a new else if
and say E dot target dot matches.
And let's see what we want to match this time.
So list view, and it's this class here.
So again, this is here, the element where our count
will be stored, and where we can update it
using the up and down arrows. So let's take this one,
and in this case we actually don't need to select
any of the children because there are none.
Okay, so it's just this element.
And so what we need to do now is to read the data
from the interface, and then update it in our state.
So let's call it val, standing for value,
and our value will be stored in the element
that was actually clicked, right?
So let's say that we, and that will be gone,
Well actually not. So let's say that we clicked this here,
and so our target will be this exact element, right?
So this input element. And if we click this one here,
then the target will be this one.
And so what we want to do now, is to read the current value
of the element that was just clicked, okay?
And what that means is E dot target.
So E dot target is the element that was clicked.
And so since this is now an input element,
we can read the value property of it,
which will then contain the number,
so the value that is in there, okay?
So very simple. Now all we have to do
is to actually parse it as a float number.
Because otherwise, it's going to be a number
which is not what we want.
Alright, and now state dot list dot update the count,
and now we have to pass in the ID and the new value.
And that's it. And it's not called value, really,
sorry, it's called val. But now, that should be it.
So handle the delete button, and now here lets say
handle the count update. Okay.
Now just notice that we're not really listening here
for an event where we update this count here, okay?
And now it's gone. But anyway, we are not looking
for the event where we update this number,
we are just looking for the event when we click here.
So that's when the event will be triggered.
So whenever you click on one of these buttons,
variables change. So let's put olive oil right here
to three, and let's then take a look
at state dot list.
Okay, so we have six.
Let's take a look at olive oil,
and here's olive oil, and yes, it updated to three.
So awesome. It really worked. Now we can delete
some of this stuff here, let's delete all of this.
Change this one here to minus five which doesn't make
much sense, and we could change that, but well,
at this point, you already know how to do that
and so I'm not going to keep boring you
with all of this repetitive code.
Let's just take a look at this again.
And we already see we only have
two elements now, which is minus five instant yeast,
and then three olive oil. So, cool. It's working,
and so we're done with this part as well.
So next up is then this like functionality,
where we can finally like a recipe,
and then basically add them to a list of favorites.
That's going to be the last thing that we're going to do,
it's going to be a bit more difficult
than this list here, but I think
it's a great addition because you will learn
some new, cool stuff. So congratulations
for making it this far, and see you in the next video.