Fetch Authenticated Data on the Client

Lesson Description
The "Fetch Authenticated Data on the Client" 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 discusses adding new services to the course app, including getFavorites, getWatchlist, and saveToCollection. He emphasizes the importance of passing authorization tokens manually in API requests and demonstrates how to structure web components using OOP, creating base and extended classes for different sections like favorites and watchlist pages.
Transcript from the "Fetch Authenticated Data on the Client" Lesson
[00:00:00]
>> Maximiliano Firtman: Now we have the server. The next step is to go to the client. So in this case, we, for example, remember our client in public services. We do have an api.js with all our endpoints, so we actually need to fill the new endpoints that we have here.
[00:00:20]
But then we need to think about this. What are the data here? We need to now add the new services. Okay, so let's say after login, we have actually three services. getFavorites, that will be async. We have getWatchlist. Actually, watchlist is one word, so I shouldn't capitalize the L.
[00:00:48]
async, something like that. And we have saveToCollection, or addToCollection, however you wanna call this, that will receive a movie ID, and also in which collection we should be saving that movie, okay? Something like that. So in this case, well, we need, for example, getFavorites should do something simple like try to return, well, let's remove the try, just to understand why we need it.
[00:01:16]
I will return await of API.fetch. This is account/favorites. So something similar to what we have done before. Does it make sense? So let's start with favorites and watchlist. So if I wanna try this without finishing the UI yet, I'm going to expose the API to the app. Remember, we do have the app.
[00:01:42]
The app is exposing the router and the store. Let's expose, just for debugging purposes, the API, okay? So that means that now I can go to the browser, refresh, and try to access the API through app.api. So if I try to get favorites, okay, it's 401 (Unauthorized). So our server is returning 401.
[00:02:07]
And you say, no, but I'm logged in. If we go to Application, okay, well, maybe we are not logged in, so let's try. If I go to my account, it seems like we are not logged in. Okay, let's try again. We have test.dev, and our very secure password that we said before that, of course, here is complaining that it's not really secure.
[00:02:30]
Okay, that's Chrome saying, hey, be careful. That's a password manager, okay? So now I do have a JWT, so if I'm seeing here, it's there. So that's the JWT. Okay, it's available there in local storage. So also, we can check that in our store, we do have the token, okay?
[00:02:53]
So it's there, we are logged in. The thing is that if we try again from here to getFavorites, we are still getting 401. Does anyone know why?
>> Speaker 2: You're not passing the token?
>> Maximiliano Firtman: I'm not passing the token. The token is not like cookie, so it's not gonna pass to the server automatically, okay?
[00:03:16]
A cookie goes automatically. So when you're working with sessions, a cookie works automatically, but not the token. This is our custom implementation. So that means that we need to make a little change to our API service, that we have two versions, fetch and send. Remember, one is just requesting data and the other one is also sending data.
[00:03:39]
We could merge both in just one if we want to. So here, we should add a new header. So we need to pass manually this, the token. And the standard way to do that, of course, you may change that, is to pass authorization, that's the name of the header.
[00:04:00]
And JWT goes there with a prefix, something like this, Bearer, and then the token, okay? So we can, well, I need a coma here because it's JSON, and then we can use template string and get from app.store.jwt, the token. The problem is that, yeah, it will add it, but maybe it's not there.
[00:04:28]
Maybe it's null or undefined. So we may wanna check if it's there or not first. So if we do have one, we pass that. And if not, we can say null. If we say null, the header will be ignored, so it will remove the header. And something similar we can add to fetch.
[00:04:51]
The problem is that fetch right now has no headers. So when we are fetching, we are not passing headers. So after the URL, I need to add a second argument that will be an object where we can set the header, similar to what we did before, and then we need at least this header, okay?
[00:05:12]
So we have added the, yeah.
>> Speaker 3: Sorry, I think JWT is misspelled on 55
>> Maximiliano Firtman: Maybe. Yeah, you're right, thank you. Again, it's autocomplete for some reason. There we are, thank you. So now we are passing, if the token is there, we're passing the token. Actually, we're passing the token to every request, which is okay.
[00:05:34]
I mean, if it's there, let's pass it. The server will decide what to do with that. Because maybe you can say, well, but maybe, to get the movies, we don't need the authorization, so we don't send it. But, but, but, but, maybe you wanna do something with that.
[00:05:48]
For example, when you get the movies from the server, if the user is logged in, you change what you are returning, such as your watchlist. I mean, when you go to Netflix, Netflix.com, the homepage, but before it has some movies. But if you're logged in, you will see also the movies that you added to your watchlist.
[00:06:07]
So maybe it's the same API endpoint, but you will get different responses, basically, if you have a token or not. Does it make sense? So that means that now we can try this again, and if I try to get favorites, now I'm not getting a 401, it's a promise.
[00:06:24]
So because it's a promise, I can wait for it and I will receive the answer. Now, in this case, it's null. Okay, we'll see if it's what I'm expecting or not, but at least it's null. I'm not getting any error. If I'm going to Network and try this again,
>> Maximiliano Firtman: We should see here the call, and we are getting null from the server, okay?
[00:06:47]
We will see if that's what we want, but at least it passes the first step that is actually receiving the email through the middleware, okay? Does it make sense? We are not getting 401.
>> Maximiliano Firtman: Okay, so the next step, and then we see if we have a bug or not, if everything is connected, is to actually connect this to the UI, okay?
[00:07:15]
So we have the Favorites and the Watchlist sections or pages that we need to actually fill. So we know how to do that. Though, it's actually at this point, pretty simple. The only thing that we need to do remember is to register the routes, create the web component, create the template.
[00:07:37]
So everything we've done so far a couple of times. In this case, we can use a template for both collections. We don't need one for Favorites and the other one for Watchlist because they are just the same, okay? Just collections, at least. So we can go here and create a new template.
[00:08:04]
It's gonna be our last template. It's a template-collection, like that. The template-collection, I think that for now, will have a UL for movies, and maybe a title that we can add later, or something like that. So we can start with a UL, with an ID, so we can later grab this by ID.
[00:08:30]
So let's say this is a list of movies. Okay, we can add a title there, so we can fill that title later. Actually, pretty simple. When you look at that, you may say, well, maybe we don't need a template. We can just write this from the web component, from JavaScript, okay?
[00:08:50]
Which is okay. But maybe in the future, if you wanna change that, it's easier if it's in the HTML. So then we are going to create the web components, and in this case, I'm going to use OOP. So instead of creating the full code in both classes that they're gonna be the same, I'm going to create the base Collection page.
[00:09:11]
And then we will have Favorites page and Watchlist page extending from Collection page, okay? Does it make sense? That's kind of the idea. So I'm going to create first the three files, CollectionPage.js, and then FavoritesPage.js, and WatchlistPage.js. Okay, the three. Now, we have already done this a couple of times.
[00:09:38]
So if you want, we can just take the from, in this case, I think it's H4. Over here, we have a template with more details. If you wanna get the same template that we have here, it's okay, you can take it from here. I'm talking about the template collection.
[00:09:58]
But the other one will work anyway for what we are going to create. And then we need,
>> Maximiliano Firtman: This is the Collection page. And the other components are simpler, okay? And we can write it manually to understand what's going on. So this is the Collection page. Probably, I will need an import some points, we'll see.
[00:10:22]
So the Collection page looks like this. Extending HTML elements, so it's actually a web component. But I'm not defining the web component, because it's gonna be a base class, okay? That will have an endpoint. What's the endpoint? The API function that we will call, and a title, and we are receiving that through the constructor, okay?
[00:10:44]
So we control the collection, we pass. This is favorites and this is your endpoint. And then this is looping through the movies and actually rendering movie item components. Okay, this is pretty simple. And on connectedCallback is just cloning the template. We have already done this a couple of times.
[00:11:03]
So Favorites, for example, is gonna be an export class, FavoritesPage, extending from not HTML element, but our CollectionPage. And the constructor of this one is gonna call super, passing the endpoint and the title, okay? Does it make sense? So for example, it's gonna be API.getFavorites, API needs to be imported.
[00:11:38]
Be very careful with both imports, not sure if you realize at this point what's going on there. So this is Favorite Movies, I need to add .js.
>> Maximiliano Firtman: And I'm going to define this, customElements.define, and this is gonna be favorite-page.
>> Maximiliano Firtman: And something very similar on watchlist, just changing the endpoint, the name of the class, Movies in Watchlist, watchlist-page.
[00:12:22]
I think I'm done with that. Okay, does it make sense? So remember, when you're using web components, you can use OOP, and create your structure of components that you just inherit behavior. And you then enhance that behavior with subclasses.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops