Thursday, April 24, 2025

Fighting with *ngFor? Let's talk about error NG9.

Let's talk more about Angular 18.

So you want to iterate through an array in Angular to use repeating sections on your UI.  Right?  Well, Angular supplies a directive called *ngFor, which essentially creates a for loop on your page. 

Let's say you're generating menu items dynamically on your page.  You could hard-code them in the HTML, but if there's any chance the menu items may change in some way, you're asking for trouble.   Besides, even HTML code should be as reusable as we can make it, right?\

Let's create a custom component whose sole purpose in life is to display a menu of hyperlinks. 

Step 1.

 Once you've generated your shiny new component, you'll need to import *ngFor, since it isn't in the Angular core.   Add this line:

import { CommonModule } from '@angular/common';

Be sure to include CommonModule in your imports array as well:

imports: [CommonModule],

So far, so good.  

Step 2.

Now, we need a data source.  Let's create an array that has a few section headers along with the name of the sections on this page we'll be navigating to.

const SECTIONS = [
  {id: 1, name: 'About', url: '#section1'},
  {id: 2, name: 'Projects', url: '#section2'},
  {id: 3, name: 'Experience', url: '#section3'},
  {id: 4, name: 'Education', url: '#section4'},
  {id: 5, name: 'Publications', url: '#section5'},
  {id: 6, name: 'Press', url: '#section6'},
  {id: 7, name: 'Blog', url: '#section7'}
];

Now we need to expose this array to the HTML template.  In the export function, add a line to do that:

export class MenuComponent {
  sections = SECTIONS;
}


Great.  Notice how we can make the variable name different from what it is internally.  You can make it the same if you like, but in this case, I wanted it to be lowercase in order to look cleaner on the template.

Step 3.

Now let's move over to our HTML template.

<html>
 <body>
   <table class="navbar">
     <tr *ngFor="let section of sections">
       <td><a href="{{section.url}}">{{section.name}}</a></td>
     </tr>
   </table>
 </body>
</html>

In this case, I'm going to use a table to display these elements.  Each row will display the data from one item in the array.  As an attribute of tr, we use the *ngFor and set it to the phrase  "let section of sections" where 'sections' is the name of the array we exposed in the component class, and 'section' is what each of the individual items will be referred to.

For each of the columns, we want to display a hyperlink with the data from our section array.   We create a basic link using 'a href' and set the target to the 'url' field from our data array.   The text to be displayed is then set to the 'name' field in the array.  

Now save it, build it and ng serve it!






No comments:

Post a Comment