5.1 Designing the Portfolio View
In this lesson, we'll design the portfolio view. It is very similar to the currency list view.
1.Introduction2 lessons, 12:18
2.Getting Started2 lessons, 20:32
3.Users and Authentication5 lessons, 54:30
4.Managing Currencies5 lessons, 46:15
5.Managing Our Portfolio5 lessons, 50:13
6.Security1 lesson, 10:49
7.Conclusion1 lesson, 00:38
5.1 Designing the Portfolio View
It's taken us a while, but we are finally to the point to where we can implement the whole reason why we are writing this application, and that is our portfolio. Now, of course we needed users, we needed currencies before we could even do anything with the portfolio, but we're finally here. So our portfolio is really nothing more than a list of things. In fact, let's look at our data model. If we look at the user, we see that we have our portfolio, it is an array of objects that have an address, and also have the currency associated with that address. So our main portfolio page is nothing more than just a list that we can edit and delete, and we already have something like that, that is our currencies. So let's use our currency view as a basis for our portfolio. So let's go to views > admin > Currencies. Let's copy that, and let's paste it into the views folder. This isn't something that is strictly administrative. This is something that every registered user will be able to see, so that's why it's not going into admin. And let's call it portfolio, and let's make a few changes. So the CSS class at the top is going to be portfolio because that is what we have done thus far. Let's change the heading to portfolio. And the add button, let's change that to add Address, because that is essentially what we are going to do. We are going to add an address. Now, the data in the table, we do need the currency name. We don't necessarily need the ticker in its own column. Instead, we do want the address, and then we don't need the URL, but we want the Balance. Now, the balance isn't going to be part of our data model, but we are going to be adding it to the data that comes from the server. So when it comes time to iterate over that data, let's use the terminology of record in records. So that means we need to change that currency property, or the data property, to records. And as far as the key is concerned [SOUND] we don't have an id, but our address should be good enough. I mean, because the way that this works, every currency has its set of addresses, and the addresses are unique in that currency, on that network. And for the most part, a different currency is going to have its own set of unique addresses. So there is the possibility of a collision, for one address and one currency to be the same address as another currency. However, that should be very, very, very, very, very rare. And in this case, I'm fine with just leaving it as the address, unless if that actually causes a problem, in which case we will come back and fix that. Now, as far the data that we display, we're going to say record.currency.name. And then in parentheses, we will include the ticker there so that it's all contained in that one column. And then we will have the address, so that will be record.address, and then record.balance. So there we go. We will leave the controls there. We don't need our creator and editor just yet. But I'm going to, actually no, let's leave them there. Let's change the path of these. I mean, obviously, we're not going to be editing any currencies here. But I'm just leaving this here so that whenever we actually do come back to add the editing and the creating, that this is here, just as boilerplate. Now our path to the API has changed, and let's see, as far as our methods, let's call this refreshPortfolio. And we need to change that. Now, as far as our client API is concerned, we can call a method called getPortfolio. And then we will set our records to the data that comes back. Everything else we can leave the same for now. And let's go ahead and implement that method. So let's go to our client API. Now, we could start segmenting this so that we have a portfolio object, which is then going to have the methods, but that means that we have to refactor the currency code and I don't want to do that. So we're just going to add in our getPortfolio method. We don't need to pass anything to this. Because the way we determine what user's logged in is through the token, which we haven't done anything with. So let's go ahead and implement that here as well, but let's first get the url. We're going to build the url with just the string of portfolio. And then we will make a get request for that. So we will return axios.get(url), and then we will have a callback that we will simply return the data. All right, so there we go. Let's have a function for building the options, because the header information is part of the options. So let's call this buildOptions, and we will accept an options object. But let's give it a default value of an object. And we want to check to see if we don't have any headers. Because if we do, then we want to go ahead and add our headers there. So then we will add the authorization header, and we will get our token from localStorage. We called that key token, so that way the authorization will be included in the headers, we will return options, and there we go. So it's basically just a poor man's merge of options in our headers. So now we just need to call that for every method that needs the authorization token, which is basically everything but the authentication methods. So we will just call buildOptions, and this way, if we needed to pass any other type of options that we could, it would just build everything together. And we need to pass that for deleting currencies, we need to pass that for editing and creating currencies. And let's see, yeah, getting the currencies as well. I mean, we could make the argument that getting the currencies, there's nothing really special there, but let's go ahead and protect it anyway. And with that, we have at least the beginning of our client portfolio code. Let's go to the router, let's add an entry for the portfolio. And that is simply going to be a path of /portfolio, the name will be portfolio, and then, of course, the component will be Portfolio. So let's go to the browser, let's make sure that this is going to at least display. Let's log in. It doesn't matter which user we use to log in, because we should see the portfolio. And now that we have this view, hey, that's great, let's see if we have any errors. We do, because for some reason buildOptions is not defined. We just wrote that, okay? So let's see what the problem there is, build, yeah, one simple key stroke and the whole thing just dies. Now, one thing I do notice, our links reset, and I know why that is. Because whenever our app component is loaded, we need to check the local storage to see if we are logged in. So what we can do then is inside of the created hook, we can check our local storage. And if we are logged in, then we will have a token, and we will have the user as well. So let's do this, after we listen for the log in, let's add a check to see if our localStorage has a token. If it does, then we are going to assume that we are logged in. So we will say this.isAuthenticated = true. But then we also need to determine if the user is an admin. So let's grab the user information, which we will parse from JSON. Once again from our local storage, we will get the item of user. And if we have a user, then we will set the admin flag to user.isAdmin. All right, so with that done, voila. We see our links. If we log out, that goes back to how it's supposed to. So if we log in once again, we can firstname.lastname@example.org, password, and let's do a hard refresh. That's the truth there. If we had to refresh then everything's good. We see our portfolio and that's great. One other thing, now that we have our portfolio, whenever we do log in, let's not navigate to the about page, let's navigate to portfolio. So we will change that to portfolio, and there we go. Well, there's one other issue that we need to fix, and that is in the portfolio it says that option is not defined. Well, that's because there's one missing key stroke there inside of buildOptions. But with that, the error will go away, and the only other issue that we will have is that our endpoint doesn't exist. So that is something that we will at least stub out in the next lesson. But we need to be able to create or add records to our portfolio so that we can then view them. And we will do that in the next lesson.