Instructor: Let's continue where we left off
in the last video, and build our loading spinner.
And in order to implement the spinner
as best as possible, let's remember
that it should appear here in the search results list,
but also here in the recipe whenever we click
on one of these results here, okay?
So, we should have that in mind
and build the spinner, this loader for reusability.
Okay, and so actually let's not include it
in the search view, but in base.js, okay?
Because again, this is not really just
for the search, but we're gonna use it
later also in the recipes, okay?
And so, base here is, basically where you put the styles
that are reusable and other stuff,
like these elements, they're also being used
and reused across different modules.
So let's say export + const + render the loader, okay?
And now we actually want to pass one argument
into this loader, and that is the parent element.
Okay, so remember what I mentioned in the beginning
that we will do this loader here for reusability,
and so the best way of doing this is to pass in the parent
and then say that we want to attach this loader here
as a child element of the parent.
And so, in the case of this list here
we can pass in this parent element here
so that the loader will be attached to this,
and if it's the recipe, we can then
pass in this parent element.
All right, so, let's create a variable
const + loader, and then using the template string method,
that I showed you before.
So we're just going to write some HTML here.
This one I can't copy from anywhere,
so let's just write it out here.
And actually even inside of Javascript here,
this HTML still gets autocompleted,
which is pretty amazing I think.
So we have this div with the loader class,
and then in there we have an SVG,
and so this is an icon.
And then use + href and then you know images,
it's the icons.svg, from which we select icon CW.
And that's it.
So how does this actually work?
So let's take a look at our CSS file here,
so that's the CSS file, let's search for loader,
and here we have it.
So we style the loader here with this height,
this width, and this fill, but the magic really happens here
which is this animation, which is
an infinite rotating animation.
So that's the animation that I defined here
with the key frames after all.
I'm not sure you're familiar with that,
but anyway, we have this animation here
which basically makes this icon rotate 360 degrees.
Then we stated that we want it to be infinite,
and so basically as long as the element is
on the page, it will keep rotating, okay.
And that's as simple as it gets.
So really simple stuff here, that's all we need
to do here in the situation.
Now where do we actually attach it to?
Well, that's the parent that we pass in.
So, parent, and then, again we use or insert
adjacent HTML.
Let's take a look again at the documentation here.
And so this time around we're gonna put it
right after begin here, so right at the beginning
of the parent element, so let's copy this
function here, I'm not going to write it out myself.
So afterbegin, and we want to attach actually is the loader.
All right, and that is it, I guess.
So, moving over to our index.js file over here,
we now need to edit here, prepare UI for results.
So the first thing that we want to do,
we're actually, not so, after clearing the results
from the search view, we now want to render our loader.
So let's say, and actually we have to import it still.
So this here, inside of this base file, right,
and so, let's actually add the renderloader.
So these are all named exports.
And we could actually have done it
with the asterisk import here.
So basically, importing everything
at the same time, but I'm keeping it like this
because later we are actually going
to add some stuff here that we're maybe
not going to use here, so we don't have
to expose it to this index.js file.
Anyway, we can now use renderloader here,
and all we have to do now is to pass in the parent element.
And the parent element, where we want this to be
is actually this, results, because the results
list is an unordered list, we don't want
the div inside of that, so this is only for LI elements.
And so let's actually attach it here in this div
so it is called results, and we need to then edit
here into of course, into this element.
So search document.queryselector,
okay.
Let's copy out this one.
So elements.searchres.
So this renders the loader.
Okay, close this one up,
and let's check it out.
And here we go, so here it is.
And it keeps rotating and rotating and rotating,
waiting for the data to come back,
and here we go, so here is our data,
but the spinner is of course, still rotating here.
So that's not ideal, and so let's get actually rid of it.
Okay, but let me just inspect it here for you to see it.
So that's the icon that we included
and with the, sorry, with the
infinite rotating animation here.
So that's our spinner.
Now we also need a method to get rid of it, right?
So let's get back to our base.js
and create the clear loader.
And this time around we don't need to specify
the parent, all we need to do is to select the loader.
Now right now we cannot really select it
like we did here in the elements,
and that's because by the time that this code runs
the loader is actually not yet on the page.
And so we cannot select anything that is not yet there.
So what we need to do here is to do
the document.queryselector right here.
So const + loader + document.queryselector,
and then the class.
Now it really bothers me to hard code this class
into this query selector here now.
I really want all of these classes like
to be in a central place, so just like we did here.
So this is a lot cleaner and in order
to achieve the same thing, we will actually create
a new object like this, elementstrings this time around.
So we're gonna call this one loader,
and it has the class name also loader,
as we already know.
Okay, so down here we now can say elementstrings.loader
and the same thing actually up here.
So if you were ever to change now the loader name
in the CSS for some reason, then all we have
to do would be to come here to this element,
change it here, and then it would work automatically
here in both of these methods,
instead of being hard coded down here
and also here in the render method.
So maybe you think that's a bit overkill,
that's not really necessary, but I like
to keep things like that because I'm always looking
for usability and maintainability,
because that's something really important in all coding,
not just Javascript, but also CSS
and whatever really you're writing, okay.
So in here we now selected the loader element,
now let's test if it exists so we can then delete it.
Okay, and actually this here is not ready yet,
because we still need to add the dot.
So let's do that using a template string,
so dot and then this part.
All right, and we cannot add the dot in here
because then the dot would also be here
in the class name, and we don't want that.
So this really has to be just the class name,
and then we add the dot here for the class selector
here in the, right in the query selector.
Anyway, if there is a loader, then you'd want to delete it.
And maybe remember from the (mumbles) app,
that deleting an element from the dom is a bit strange,
so we have to go up to the parentelement,
so parentelement, and then basically
we move down again and remove the child.
Okay, so in order to remove an element,
we always have to remove the child,
and in order to do that, we need to move up to the parent.
Okay, and so, we pass in the loader again,
which is our element, and that should be it.
Okay, so what we want to do here is when we render
the results, we first want to start
by removing the loader, okay?
And again we need to actually ascertain here.
Or import it, so we want to render and we want to clear
the loader, so all these methods
we want it to be available here,
and so let's say clear the loader,
and that should do the job.
So it already reloaded, let's search
for pizza again, whoa, what's that.
Well something's wrong here.
I mean it did functionality, so it added the loader
and it then it removed it, but I guess something
is wrong with the class names.
So yeah, of course it's not elements,
it's elementstrings,
so here and down here, it should be elementstrings,
give it a save, let's try it again.
And yeah, here we go, so it rotates
and it disappears as soon as the results come back.
So that's exactly the look that we were for.
Okay, now next up we have to implement the pagination.
So right now we have all these 30 results,
all on the same page, and that's not really helpful
because it makes the page way too long.
And so what we want to do is to have three pages
with 10 results on each, and so,
in the next lecture, that's what we're gonna
take care of, so see you then.