2.5 The Project Summary Component
Instead of just listing the titles of our projects, we want to display more information about them. In this lesson, we'll build a project summary component, which will display each project as a neat card.
1.Introduction5 lessons, 29:28
2.The Projects List6 lessons, 39:35
3.The Users5 lessons, 31:28
4.The New Project Form4 lessons, 30:48
5.The Project Page4 lessons, 49:46
6.Conclusion2 lessons, 04:08
2.5 The Project Summary Component
In this lesson, we're going to create a project summary component, which we will display each one of our projects in on our Projects list page here. So let's start by creating a project summary file. So we'll have projectSummary.component.ts. And once again, we'll import the component decorator and we're also going to need OnInit, as we've seen before, and this time we'll also import the decorator input. So let's start by creating our component here. We'll give it a selector of 'project-summary' and we will set up a template, projectSummary.component.html. All right, let's go ahead and export our class here. And we're calling this ProjectSummary, and we're going to make sure that this implements OnInit. And with this in place, let's talk about how we get a project to display in our ProjectSummary component. Now our ProjectSummary component is not a top-level component, in the same way that our ProjectsComponent is. Over here in our ProjectsComponent, the way we got our project models here in our projects component was by providing the project service, and then we get that through injection, and finally we can call a method on that service to get our projects from the server. However what we're going to do is from within our ProjectsComponent. We're going to render our projects as a bunch of project summaries and so for ProjectSummary we don't need to get a project from the server we can just accept it as input from our projects component. So let's see how we will use this. If we open up the template projects.component.html, instead of our h1 that we have here, we're going to call project-summary and we're going to do our star ngFor on this element instead. So it say let project of projects here and we can delete our h1. And what we need to do is provide our individual project here as an input to project summary and the way we can do this is by binding this project variable which exists outside the project summary to a property inside the project summary. So what we can do is say [project]=project. Okay, so what's going on here? Two things we need to notice here. First of all the word project here are two separate projects. The one in the quotes here as the value in this key value pair is the project that we have outside where we say let project of projects. For example I could change is here to be myProj and then this here would have to change to myProj as well. So these two values refer to the same thing. Now the key for this attribute project here refers to the project property inside of the project summary component. The square brackets here basically perform the binding. They say bind this value from the inside to this property on the inside. And this is some new syntax and angular too. It's a little tricky but once you get used to it, it makes a lot of sense. Square brackets mean we're putting something from outside of our component here into this specific component instance. So, we're signing to this project property. Now, we don't yet have a project property here inside of our project summary. So, let's go ahead and create that. Here, we're going to have a project property that's going to be of the type project. Now we can't actually refer to this project class unless we have it in this file, so let's go ahead in import project from our project definition. There's one other thing we need to do here and that is this input decorator this input decorator goes on this project property and that way angular knows that this project property that we're binding to here is the same project property that you're looking at right here. So we can just call this input decorator right before the project property. And sometimes you'll see this put on the next line. You can do it however you want, I like to keep things on one line. And now, we can use this project property from within our project summary class and from within the template to display this project. And so let's go ahead and use it in our template. We'll create in the templates directory a file called projectSummary. Summary.component.html and in here we're going to use the material design card. So will say nd card the first attribute in here will be the nd=card=title and nd=card=title is going to have a link. To the individual project page. So we'll create an anchor element here and this anchor element will have the project name in it. Now if this were a normal anchor element we would just use the href attribute. However, because we're using Angular as router Instead we use the router link attribute and router link is a property that we are binding to just like we bound the project object to the project property on ProjectSummary. So what we're going to do is right or link has to be in square brackets and then of course its value is inside quotes. And so this is binding some value to the routerLink property inside of this native angular component. So usually to routerLink you'll pass an array. And each one of our row components will be a member in the array. So we start with /projects here. And then we also pass it project.id. And so what we're basically doing here is creating an anchor that will go into /projects /project.id. And a bit later on we'll set that up as one of our roads and we'll have an individual project page. The next property will have here is md-card-subtitle and this is just where we will use the project description and finally we will have md-card-content which will be the main content of the card. And in here we're going to have a paragraph and this paragraph will get the project.conversation.length to get the number of conversations so that we can show how many conversations are in here and then underneath this what we want to show is the avatars of the users who are involved in this project. Now, right now the project will have an array of users. If we go to /api/projects, you can see here we have, well this is our first project here. And you can see we have a user's property which just has the user names of the four users. So what we need to do is get their user objects from the server, so we can then display their avatars on the page. Now, we could create a user's service if we wanted to for this. And for a more fully featured application that would probably be the right thing to do. But we're just going to throw this method inside of the projects service that we've already created. So we'll create a method called getUsers and this is going to return an observable with just an array of objects in it and we will say return this study http.get/api/users and then we'll map this two to extract data. And now we have a quick and easy method by which we can get the users from the server So let's come back to our project summary class here and let's import that. So import the projects service. And then of course we will add it as a provider to the class. And the last step, we will add it in the constructor so that we can access it from within methods. So now inside of the ng on Init method. Which you'll remember will be called when a component is initialized. We can go ahead and get those users, so we'll say this.service.getUsers. Then we can say .subscribe to get that list of users, Subscribe will receive a list of users. So in here we can do this.avatars. So we're going to create an avatars object which will just be an array of strings. Let's add that as a property up here, we'll say avatars will just be an array of strings. And then what we can do is we've got the users And then let's go ahead and say dot filter. This list of users by each user and for each user we will look at this dot project and remember this is the project that we're displaying with this instance of project summary. So we'll say this.project.users.indexOfu.username. So we're looking for that username of whichever user we're filtering over in this array of users. And if we find it meaning we are greater than minus one then we will return that and so now we have an array of just the users. And then we can map over each user and we can just return user.Avatar. And so now avatars here is an array of the user's avatars. And so now we should be able to just display that array of avatars. So let's have an image here we'll give it the attribute /md-card-avatar and then we'll also give it a class of avatar. And then we can use that *ngFor='let a of avatars' combine the [src]='a' />. I do want to make something clear here. An alternative way to do this that would work but would be the wrong way to do it would be to say the source. Equals and then we can insert the link in there using the intercalation syntax. The problem with this is that when the browser sees the source attribute, it will try and download this as a file but it's not going to see the actual URL. It will see double curly brace a, double closed curly brace, because angular won't reach this source attribute before the browser does. And therefore, by using the square brackets index, we can be sure the browser will never see a source attribute that doesn't have an actual link as its value. Because angular will convert this syntactic sugar behind the scenes, and make sure that the browser only sees the right thing. All right, now before we bring this to the browser let's go ahead and add the project summary components in our module. So we'll open up at module underneath our projects components here let's import the project summary from project summary dot component and then down here in our declarations we will add project summary. And if we come back to the browser, it looks like we have an error. And you'll find this often when developing with Angular too. If you just look in your browser console, you'll look at this error and it will be so unhelpful, unexpected token period. And if we go to the link, it just shows us where we're doing our system import in our index study.html file. So that's not very helpful at all, and you might think, well do I have to go through all the code I've just written to find some unexpected token? Not quite, if you come back to our typescript server you'll probably find the error there. So, as you can see since our last compilation here we've had a couple of errors in the project summary component. There's an error on y9, so let's begin there. If we come to line nine here, you can see obviously we have a curly brace instead of an ending square bracket. You probably already noticed that, so we'll go ahead and we'll change that. And it looks like we still have a few errors here on line 19 and 21, if we come to line 19 here. Yeah, the errors actually appear in line 18 where we need to have an arrow instead of just an equal sign. And that will probably take care of most things. One other major problem, we just called this class project summary instead of project summary component. All right, and it looks like typescript is satisfied now. And so now if you come back to the browser, you can see that things are looking really good here but we'll take care of that in the next lesson. But notice that we have our title at the top, and if you look down in the very bottom left hand corner of the browser window you can see that we do have the right URL here projects/5 for this one projects us 11 and this is project slash 14. We have our descriptions as subtitles or with number of conversations and then we have the users being displayed via their images. And so there you go, we're successfully displaying our project summaries.