3
votes

Im having a strange issue with trying to use ngFor and ngIf in a template tag. Im trying to display a label title inside an Analyst object like so:

The Analyst Object:

class Analyst {
  private _properties = {labels: [{title:'a'}]};

  get labels() {
    return this._properties.labels;
  }  

  set labels(labels:Array<string>) {
    this._properties.labels = labels;
  }      
}

The component template:

<div *ngFor="let analyst of analysts; let i = index">
  <h2>Analyst {{i}}</h2>
  <template ngFor let-label [ngForOf]="analyst.labels"
                              [ngIf]="analyst.labels.length > 0">
    <div>{{label.title}}</div>
  </template>
</div>

I keep getting an error

cannot read property 'title' of undefined

The error disappears in the following cases:

  • When removing the [ngIf]
  • When using json pipe instead of title attribute {{label| json}}. The json string that is printed to the screen includes the title attribute.

A link to the full code in plunker

Can anyone please explain why this is happening?

Thanks!

2

2 Answers

3
votes

You can't have more than one structural directive on the same element

Use instead

<div *ngFor="let analyst of analysts; let i = index">
  <h2>Analyst {{i}}</h2>
  <ng-container *ngFor="let label of analyst.labels">
    <div *ngIf="label.length > 0">{{label.title}}</div>
  </ng-container>
</div>
1
votes

you cannot have more than two structural directives on same element

@Component({
  selector: 'my-app',
  template: `
  <button (click)="addLabel()">add</button>
  <div *ngFor="let analyst of analysts; let i = index">
    <h2>Analyst {{i}}</h2>
    <template ngFor [ngForOf]="analyst.labels" let-label>
            <div *ngIf ="analyst.labels.length > 0">
          <div>{{label.title}}</div>
          </div>
      </template>
    </div>
  `,
})