3.6 Displaying the Content
We'll finish the basic UI in this lesson by implementing the content panel.
1.Introduction2 lessons, 07:37
2.Getting Started2 lessons, 17:11
3.Writing the Basic Functionality6 lessons, 52:36
4.Adding Settings3 lessons, 28:18
5.Managing Screen Sizes1 lesson, 08:03
6.Authentication and Authorization4 lessons, 27:46
7.Conclusion1 lesson, 01:06
3.6 Displaying the Content
In the previous lesson we almost finished the functionality for our item list. So that whenever we click on a given feed the items are loaded. And now we just want to follow the same concepts. So that whenever we click on one of these items, it will load the content in the content router outlet. So let's just get started. And we'll do so by creating a new component that's going to contain our content. So we will generate that component, we'll just call it ContentContainer. And while it does that, let's go ahead and set up the route. So let's open up our routes file, app-routing, there it is, and the route is going to be very similar. So the path is going to be item slash and ID, that way we know that this is for a given item with the given ID. And the component that we want to use is going to be that new ContentContainerComponent. And Visual Studio Code looks like it already knows what that is, it does. So then we want to specify the outlet, and that is just simply content, so there we go. We have our route set up, so that now we can navigate there. So let's go to our item list template, because we want to set up that router link and that's the first thing that we will do. So we will bind that to our link information. The first thing is going to be the primary route, which is just going to be to the root. And then we want to specify our outlets, so we will begin with that property outlets. Now you can navigate to as many outlets as you want. So if you click on one link and you want to load things in multiple outlets at the same time, you can. Because all you have to do is specify the outlet, which in this case is content. And then provide the path for that outlet, which in this particular case is going to be item. And then the second segment is going to be item ID. Now if we wanted to load something in another outlet, we would just add a comma, have the name of that outlet and then provide the URL or the path, I should say, the path as an array. But you can add as many outlets as you want. Which means that you can do some pretty cool stuff using navigation and the router. But this is all that we need to do. We want to navigate using the content outlet with item and then the item ID. Now we want that same router link active, so that whenever we click on the back button or the forward button, the active link is going to be displayed. So, that was mat-list-single-selected-option, that is a very long, but at least you know what that class is for. And then finally, we are going to set the state and we're going to set that to this item. And the reason being because we don't need to fetch that information from the server. Now for our item list, yes, whenever we clicked on a feed, it made sense to go out and fetch the latest information from the server. Because whenever we select a feed, we want the latest items for that feed. The content isn't going to change all that much. And if we already have the items and the content for those items, then it just makes sense to pass the item so that we can get the information that we need from it. So there we go. We have our router link, we have the router link active. And then we are setting the state to this item that we are displaying. So with that done, we should be able to go to the browser and at least see the navigation working. And it does, and that's great. And if we click on back, we can see that everything just flows like it should. Of course, the content doesn't change because we haven't set that up. So let's do that, let's go to our content container. Let's open up the template, and let's open up the TypeScript. And as far as the template is concerned, let's do kind of what we did in the previous lesson to where we worked with an observable, but in this case it's gonna be called item. So we will use the ngIf, and we will have our item observable. We'll pipe that to async as item. That way, if we don't have an item, then nothing is displayed. There's no error, there's nothing, it just works that way. But if there is, then we have an item. So that then we could have our title displayed. And we could use that mat-subheader, so let's go ahead and add that there. And then we can have just a div element that contains our item's content. So there we have that. And that's it for this template, we can close that. Now we do need to keep in mind that item is going to be observable. So there are some things that we will need to do to ensure that. But the first thing that we need is our activated route, and so we can get that in the constructor. We'll just call it route and that was ActivatedRoute, and there we go. So we have the route. So instead of our init method, we will use the route. We're gonna use a property called a paramMap. And you can see that this is an observable that contains a map of the required and optional parameters specific to this route. And we want to go ahead and subscribe here. And this is going to give us the ability to get the state of the route. So we can go ahead and do this, we'll say item$ for our observable. And then we will get the state from window.history.state. And actually, let's do this. We'll start like this. So we'll have this item. And I'm getting ahead of myself, let's just do this. We'll say this item$=, and this is going to be an observable. But at this point in time, the state that we have is not an observable. But we can easily get around that by using the of function. Whatever we passed of, is going to create an observable of that object. So if we do that, then we have an observable. Now we do need to import of, that is part of rxjs, which is also going to give us the observable. So let's go ahead and import that. And then let's create that item$. And that is an observable of FeedItem, which we also need to import, and there we go. So with that in place, we should be able to go to the browser. And after this reloads, then whenever we click on one of these feed items, then the content should be loaded. And we can see that that is the case. Let's go to the second feed. And we can see that we have the title and we have the content. Styling could use some work, but we at least have the functionality there. Now, here's the thing. This works great, however, let's just refresh what happens. Well, we still see that we had the second feed selected. We had the second feed, Feed Item 4 selected, but the content is not here. And the reason is because we've lost that state. The state is no longer part of that route because we didn't specifically click on it. All of this information was actually loaded because it's part of the URL. So what we need to do then, is check to see if we have state to work with, and if we do, then great. If not, well then we do need to go ahead and fetch the item so that we can display that information. So let's go ahead and let's do that. So we will check to see if we have a state, and if so, then great. We will use that, make an observable out of it, and there we go. Otherwise, we need to use our service. So we need to bring in our service, so we will have that injected for us. And then we also need a method that's going to allow us to fetch an individual item. So let's open up our feed service. And we will add another method here. Let's just copy what we have, and we will call this fetchItem. And we will still specify the ID there. Our URL is going to be items and then ID and this is going to get a feed item. So with that done, we should be able to use that method. So that if we don't have any state, then all we have to do is fetch that item using our service calling the fetchItem method. And we will pass in the ID, and we get that using this parameter, we will get the ID parameter. And we want to parse that as an integer. So there we go, and that should work. So now we can go back to the browser, and whenever this finally refreshes, well, that didn't do what I wanted. Let's do a hard refresh, maybe we just need to reload everything. And something still is not working there. Let's, first of all, see if we have any errors. And no, we don't, let's check the compilation, no, we're good there. So the next thing that we should check is the network. Let's make sure that we are fetching that item. So this is for the item with the ID of 14, so we should be looking for 14, and I'm not seeing anything. So let's do some scientific debugging. Let's see what we have as far as item is concerned. So let's write this to the console, and this will tell us whether or not this is actually becoming truthy or falsy. So let's look at the console, what do we have? And yeah, okay, so we have an object, which is why this isn't working. That will actually work okay. What we could do is just use one of our properties. And let's just use content, so that if we don't have content, then we will go out and fetch that. So, there we go, that's the behavior that we wanted so that we can select whichever one that we want. Let's go to the first feed and we'll select Item 4. Whenever we refresh, Item 4 will be reloaded, because we made that request. However, whenever we click on any of the other items, that is going to be loaded from state and we're good to go there. So as far as the basic functionality is concerned, we're done. We have our three panels, we can select a feed, we can select a feed item and we can show the content for that item.