Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine ngIf with ngFor

Tags:

angular

I am new to Angular.

I would like to to print list of products, which are in relation with distributor. For that I thought about combaining *ngFor *ngIf so here is a code:

<div class="distributors-here ui-g-12" *ngIf="distributors">
  <h2 >Distributors  <i class="fa icon fa-plus"(click)="showDialog()"></i></h2>
  <p class="error-message" *ngIf="errorMessage.length >0">Operation couldn't be executed:</p>
  <p class="error-message">{{errorMessage}}</p>
  <ul class="distributors-list ui-g-12">
    <li class="distributor-item ui-md-3 ui-g-6" *ngFor="let distributor of distributors ">
      <i class="fa icon fa-times remove-distributor"(click)="removeDistributor(distributor.id,distributor.name)"></i>
      <div class="distributor-item-content">
        <p>id: {{distributor.id}}</p>
        <p>name: {{distributor.name}}</p>
          <div *ngIf="products">
            <p>products</p>
            <ol>
              <li  *ngFor="let product of products" *ngIf="product.distributor.id == distributor.id">dist</li>
            </ol>
          </div>
      </div>
    </li>
  </ul>
</div>

So I want to loop over the products array and if the distributor id of product matches with distributor id from other array I will have it printed new li element created.

Unfortunately I get an error:

Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *

[ERROR ->]*ngIf="product.distributor.id== distributor.id"

Does anyone knows how to refactor this code to make it work?

like image 400
Jake11 Avatar asked Nov 29 '22 22:11

Jake11


2 Answers

Angular doesn't support more than one structural directive on the same element, so you should use the ng-container helper element here. FYI ng-container does not add an extra element to the DOM (the ul in Example 2 does get added to the DOM).

Example 1

<ng-container *ngFor="let product of products" >
   <li *ngIf="product.distributor.id == distributor.id">{{ product?.name  }}</li>
</ng-container>

or

Example 2

<ul *ngFor="let product of products">
  <li *ngIf="product.distributor.id == distributor.id">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </li>
</ul>
like image 140
Sachin Tiwari Avatar answered Dec 06 '22 12:12

Sachin Tiwari


You cannot use multiple structural directives on one html element. For example you can instead place your *ngFor in a <ng-container> and wrap it around your <li> element. The advantage of <ng-container> is the fact, that it doesn't introduce extra levels of HTML.

<ol>
  <ng-container *ngFor="let product of products">
    <li *ngIf="product.distributor.id == distributor.id">dist</li>
  </ng-container>
</ol>
          

For more detail information have a look at the Official Angular Documentation (One structural directive per host element)

like image 29
SplitterAlex Avatar answered Dec 06 '22 13:12

SplitterAlex