Lesson 3 - *ngFor

The *ngFor directive is very powerful and allows us to build our page dynamically without relying on a mountain of JS to do so. I went over the benefit of that in Lesson 1, so lets get right to it. This directive utilizes for..of, so if you need a refresher on that, check out Lesson 2.

The Example

We have the following array"

fighters = [ 'Ryu', 'Ken', 'Guile', 'Sagat', 'Laura' ]

And we want to create an unordered list that displays each name in our array. How can we do this? Let's start with the basic markup structure:

<ul>

<li>

</li>

</ul>

So where do we put the darn thing? The important thing to remember regarding placement is that we place the *ngFor directive on the element we want repeated. In this example, we want the <li> element to repeat for each of our fighters, so that's where we will put the *ngFor. If we had attached it to the <ul> elements, the entire list would repeat itself, and that's not what we want.

<ul>

<li *ngFor="">

</li>

</ul>

We've got our directive in there, but what goes inside? Next, we declare our for loop using for..of style. We went over this in lesson two, so lets how see how it looks:

<ul>

<li *ngFor="let fighter of fighters">

</li>

</ul>

Let's review a little bit: We declared a new variable named fighter. We could have named it whatever we want; we chose fighter so that we can understand what we are looking at when we look at the code at a later time, we just need to remember that anytime we want to utilize this variable, we need to call it by the name we just declared. Also notice that we declared this variable to go through the arrary fighters. This is the name of a previously declared variable, so we have to make sure we get the name right.

Now that we have a variable that will represent each value of the array, we can call that value in our markup using our good friends: {{ }}

<ul>

<li *ngFor="let fighter of fighters">

{{ fighter }}

</li>

</ul>

And we're done! This will display a list item for each of our fighters, resulting in a dynamically built list.

Taking it one step further: Properties of our variable

This is super cool, but in real world practice, we won't always be simply iterating over strings in an array. Often, we will be iterating over objects instead. This example will show you just how powerful *ngFor can be. Now lets say we got the following array of objects:


        

Now, instead of simply displaying the name in our list, we want to display every property in our object. Lets set up the markup first:

<ul>

<li *ngFor="let fighter of fighters">

<p></p>

<p></p>

<p></p>

</li>

</ul>

Remember that similar to *ngIf, the directive *ngFor will affect not only the element that we attach it to, but all of its children as well. This means all of our <p> tags will also be repeated.

So how do we display each property of that object? Remember that the variable fighter in our for..of will hold the value of every item inside our array. We know that our array is an array of objects, therefor the variable fighter will also be an object. Because of this, we can call the properties of said object like so:

<ul>

<li *ngFor="let fighter of fighters">

<p>Name: {{ fighter.name }}</p>

<p>Origin: {{ fighter.origin }}</p>

<p>Style: {{ fighter.style }}</p>

</li>

</ul>

And we're set! Now we will get a list items for each of our fighters, and each list item will have three p tags that will display their name, origin, and fighting style.

What if I also want to display the index? You told me last lesson that you would show us how.

Including the Index

If we want to include the index inside our html with *ngFor, you would declare it like this

<li *ngFor="let fighter of fighters; let i = index">

And that's it. Now, in addition to using the variable fighter to get each value of the array, we can also use the variable i to get its respective index as well. If we were to apply that to our example, the code would look like this:

<ul">

<li *ngFor="let fighter of fighters; let i = index">

<p>Array Index: {{ i }}</p>

<p>Name: {{ fighter.name }}</p>

<p>Origin: {{ fighter.origin }}</p>

<p>Style: {{ fighter.style }}</p>

</li>

</ul>

The result looks like... (I shrunk it down a bit)

Is that a good example of the index?

zzzzzzz........

Outstanding.