Build a Fullstack App with Vanilla JS and Go

Creating Favorites & Watchlist Pages

Maximiliano Firtman
Independent Consultant
Build a Fullstack App with Vanilla JS and Go

Lesson Description

The "Creating Favorites & Watchlist Pages" Lesson is part of the full, Build a Fullstack App with Vanilla JS and Go course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano walks through implementing the ability to add movies to favorites and watchlists. He also discusses carefully structuring code, filling API gaps, and ensuring components are correctly imported for a fully functional web application.

Preview
Close

Transcript from the "Creating Favorites & Watchlist Pages" Lesson

[00:00:00]
>> Maximiliano Firtman: So the final step will be to actually create the routes. So, the path for example, I think it was account/favorites. The component is FavoritesPage, and do we need logged in through here, yes, cuz we need the user to be logged in. Remember we have done that with the router, so now we have a system where if a route needs logging, it will just work.

[00:00:33]
And something similar for the watch list.
>> Maximiliano Firtman: Okay, so now if I refresh, I should be able to get into favorites and watch list. If I refresh, and you can see right now, it's saying there are no movies. So I'm not getting a page error or not found, it seems to be the page, but there are no movies because, we know that when we are going through that, if you see the network favorites is trying to bring the favorites, that right now is null.

[00:01:10]
And watchlist is also getting, well actually it's getting favorites watchlist. So we have a bug, that's because I copy and paste it. So I think that on watch list page, I also need to change the endpoint. Does that make sense? So now this one will actually get from watchlist that is a different collection.

[00:01:32]
So if I go to watchlist, now we can see it's using that endpoint. But of course, right now my database is null, so we don't have any collection, so we need to add to the collection. That's the last step before seeing this, if everything works. Adding to the collections right now, we will make just the basic part, and you will have some homework to do the more advanced part.

[00:01:58]
That is, for example, having a way to remove a collection. Right now, when we add a favorite, it will be there forever, okay? But the other part is pretty simple, it's just adding the remove service as well. So to answer the collection, we need to actually create a new service that will be called from where when you're.

[00:02:20]
When you are watching my movie, when you are seeing the details of a movie, we have these two buttons, okay? So these two buttons, let's try to analyze where they are. So if I go to my index html, I and look for those buttons, those buttons will be available.

[00:02:39]
In template movie details, so they are here, okay? And we have the button Add to Favorites, Add to watch list that they don't have any click handler, okay? So I need to bind an event handler to those, and there are two ways to do that, I can do it from here, from HTML, okay.

[00:03:01]
As we did with other buttons, but we may have a problem if we do that in this way, I'm not sure if you realize what's the problem. I mean, I can say add and add to favorites, or however you wanna call this, or maybe save to collection. So we use the same function for both.

[00:03:20]
The problem is that to save to a collection, I should pass the ID of the movie. And I'm writing a template right now, where should I get the ID of the movie? Does that make sense? Yeah. So if I here need to pass an argument, let's say I wanna pass, this is gonna be a favorite, so that's the collection.

[00:03:40]
But then I need the ID, of the current movie, or the movie that I'm rendering. But where should I get the ID from? So, there are two ways to solve the problem, I think we will solve the problem in the cleaner way, or I think it's a cleaner way, but lemme show you the dirty way first.

[00:03:59]
The dirty way will let you do something like this, what if we, when you're using the DOM, you can, for example, talk to your parents, the parent is actually the parent element. So if I'm in a button, the parent will be a section. So maybe later, through JavaScript, you can check the ID here, so then you can get the ID with something like this, I'm not saying this code will work as it is, but to give you the idea, it's a little dirty, okay.

[00:04:30]
It works, but it will solve the problem because later from Javascript, you will inject that ID as a custom property, and then we work, okay. But I think in this case, it's gonna be better to just create the event listeners, when we are creating the details page. Remember that here we are creating the cast, we are doing all this binding.

[00:05:00]
Well, here we can add we can say, you know what I will go and grab from here we have two buttons, maybe if you want, we can add ID, so it's better to find those buttons. So maybe that's okay, like button favorites. I can use the DOM also to just find the first button, and the second button, but maybe later.

[00:05:20]
A designer thinks that, well, we should reorder the buttons and then then everything blows up. So that's why it's better to just do this. So then I can try and get, well, now it's an ID, so I can use get element by ID. Gavi, remember? Now you have get movie by ID, which instead of get element by Id as possibilities.

[00:05:47]
So get element by Id will then now I have the button for favorites, so I can add, an event listener for tick like this. And something similar for watch list. And here I can go and what, I wanna call you up, and I wanna save this to a collection, and where is the id?

[00:06:14]
Well, I actually have the movie here. So I will just say this movie id, and this is gonna be favorite, that's the collection. And for watchlist, remember this is the render method of our work component that is gonna be executed every time we are rendering a page details.

[00:06:38]
So, when we are doing that, we are also binding the action listeners for our two buttons. Okay, this makes sense? So I don't have yet the code, so it's not gonna work, but if I open the console and try to click these buttons, it's not working, so let's try to debug what's going on.

[00:07:04]
So actually, if you look at the html, so there are some hashes here that shouldn't be there, this is html. So it's just the id, just that. But we didn't get any errors, so anyway, we should, the thing is, what happened is when you do get element by id, and returns nothing.

[00:07:27]
It's undefined, so it should give us an error anyway. Remember, you can always try this from the console as well.
>> Maximiliano Firtman: When you are doing the console, remember that these you are not in a web component, so this is not gonna work, so you need to check and try with document, for example.

[00:07:51]
And now you see that we do have the button. So that means that now when you click here, something will happen, the problem is that, we don't have yet the function.
>> Maximiliano Firtman: Okay, so we need save to up, save to collection. So, save to collection, we just need to call our method.

[00:08:14]
So that's the last,
>> Maximiliano Firtman: Part that we will have, so we will go to public app.js. And the last service that we will have here somewhere, for example after the logout is the save to collection. We already have one.
>> Maximiliano Firtman: On h5 this is our save to collection, and now let's analyze what it's trying to achieve.

[00:08:48]
So save to collection first is verifying if you are logged in or not. Why is that? Because of course, you can click in a button and you are not logged in. Does it make sense? And we don't wanna save anything, because the user is not logged in. So what we are doing here, if it's false, we are sending the user to the account page.

[00:09:13]
But the account page needs login, so it we will be redirected to the login screen. So this is a quick way to say, okay, is this, you need to go and log in. Okay? Because if not, it's not gonna work. If you are logged in, I will try to save this to a collection.

[00:09:32]
And if it's a favorite of a watch list, I will then, after clicking there, I will send the user to that url. And that will give me directly the list of current favorites I should see the one that I have just created. Okay, does it make sense? Something important here is that I should use constants to avoid these issues, but I'm using singular favorite and watch list.

[00:09:58]
So we need to be very careful when we are calling this, in this case from our movie details page, that we are using the same collection type. Because the constant is different, and then it's not gonna work. Now that we are ready to try this, let's first fill some gaps that we have.

[00:10:21]
Let's say for example, in our html, we are actually binding these buttons. So something that we can do always, and maybe it's a good idea, mostly when you are doing web components, if those web components are not using shadow DOM. Remember Shadow DOM will let us make like a small little Dom, just for the web component, and we are not doing that in this project, so we are not using Shadow DOM.

[00:10:50]
Is that maybe we can be more specific when we are doing even if it's an id, okay, for example, we could say that, we want the button inside actions. So instead of using a by id, let's use query selector. And because it's squared selector, I need a css selector, so I need to add id.

[00:11:10]
And then you can say, you know what it's not any button, even if it's an id, and it shouldn't be duplicated, you don't know, it may be. The browser will never enforce that, so I can say this inside action. Okay, so I'm saying this button inside actions, that's one thing.

[00:11:28]
Then we have a gap in the API, because we have already added the authorization token, but we are not saving to the collection. So we are getting favorites and worksheets, but saved to collection is empty, so we need to fill that gap, so save to collection. Remember, receives a movie id, and a collection and need to send that to the server.

[00:11:53]
We are not going to use fetch for that, because we are sending data. I remember when we are sending, we have another function that is send. So we are going to return wherever it's coming from API.send, and the service name is account forward/save to collection. Okay, this should match exactly what you have, in your main.go in this case, save to collection.

[00:12:22]
Okay, so it's matching that. And then we need to pass the data. And for the data, we're going to pass an object, that will contain the movie id and the collection. Remember here I'm using the JSON shortcut available in JavaScript, so this is like saying movie id is movie id, collection is collection.

[00:12:44]
Okay, so you'll need to do that, we just pasising the option like. And we also need to check that, were in this case our collection the abstract page, is actually creating new instances of movie item component. A movie agent component is currently not imported, so we need to use contrast space and add that import and remember, our friend VS code is not adding in.js so I need to go and add the.js, okay?

[00:13:23]
At least to see if everything works. So let's say now, I will refresh, I will get into a mad max and I will see what happens if I click on Add to Favorites. I click there and boom, I'm in the favorite section and I'm seeing Mad Max already there in the table.

[00:13:45]
If I'm going to watch list, I still there are no movies. Remember, you see that little animation for a while that is loading that's the loading animation that we have done. So if I go to other movie, no Jurassic World, I add it to my watch list It's there in my watch list.

[00:14:01]
So I can go now to favorites. I see Mad Max, I can go to watchlist, I see Jurassic World, and of course, I should be able to log out, so now if I go to favorites, it sends me to log in, I cannot see them. And if I log in, test@test.dev, I should be able now to to see again my favorites and my watches.

[00:14:27]
And of course, I can add more okay to both favorites. Okay, and watch this if you want the same movie can be in two different collections at the same time. Okay, that's make sense? So as I mentioned, yeah, there are more things you can add. You can add, for example Here, like it can be like an X button, that you can delete it from there, or you can ask the user you sure you wanna delete.

[00:14:49]
So there are still more actions that you can add to this project, but now we have the full project working. So we have a home page, that is rendering top movies and also random movies every time I refresh, I'm getting new suggestion to watch today. I can get to the details of a movie, in this case, I have the Youtube trailer and some information.

[00:15:13]
Well, in this case, it seems like this one has no enough information, this movie compared with other movies, it has no cast, that's part of the dataset. The one that I picked has no cast, so here we can see Michael Keaton. I can add these movies to favorites or to a watch list.

[00:15:34]
I can see my account, I can log out, I can also search movies remember that we can search movies from here. So if you wanna search Harry or Harry Potter, I can see all the movies with Harry. I can reorder this, by score, by release date, okay, by name.

[00:15:52]
And I can filter by genre, so I can see only comedies with Harry work somewhere, okay? So we have a fully working, full stack project, that we did mostly from scratch. Yeah, there were some pieces that we pasted, just to avoid spending too much time coding. But from the database creation, importing the data to the front end, to the login, the JWT token authentication, we have the full app ready.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now