How to use ngIf and ngFor together for the same HTML element in Angular
It is a short tutorial about an issue when ngFor and NgIf directives are together used in the HTML element.
- Can’t have multiple template bindings on one element. Use only one attribute prefixed with
- ngFor andngIf on same element producing error
ngswitch
andngif
together in a single HTML element
As per Angular documentation, ngif
and ngfor
directives are not used in a single element For example, If both these directives are used in a single element it throws an error Can't have multiple template bindings on one element
You can see my previous about Angular button click event example
Can’t have multiple template bindings on one element error in Angular
In this example, We are going to use the same directives in a single element div
.
<div *ngIf="hide" *ngFor="let employee of employees;"></div>
Let’s create an Angular component.
The angular HTML template component
<h3>Multiple Directives in Same Elements</h3>
<button (click)="showTable()">Display Table!</button>
<div *ngIf="hide" *ngFor="let employee of employees;">
<span>{{employee.name}}</span>
</div>
import { Component, OnInit } from "@angular/core";
import { Employee } from "../app/employee";
@Component({
selector: "app-multiple-directive",
templateUrl: "./multiple-directive.component.html",
styleUrls: ["./multiple-directive.component.css"],
})
export class MultipleDirectiveComponent implements OnInit {
public hide: boolean = false;
showTable() {
this.hide = !this.hide;
}
employees: Employee[] = [
{ id: 1, name: "Ram", salary: 5000 },
{ id: 2, name: "John", salary: 1000 },
{ id: 3, name: "Franc", salary: 3000 },
{ id: 4, name: "Andrew ", salary: 8000 },
];
constructor() {}
ngOnInit() {}
}
The above component throws an error.
Can’t have multiple template bindings on one element. Use only one attribute prefixed with: The reason is Angular does not support structure directives🔗 in a single element
Angular does not allow to use of the ngIf
and ngFor
Directive in the same element like div or li or td or HTML or custom element. What is the solution?.
how to use ngif and ngfor together in angular
ngIf
, ngFor
, and ngSwitch
are Structural directives and these directives do host and descendent binding. When you apply the same host element, the Angular compiler is not able to decide which one to consider and which precedence.
There are multiple solutions to handle this
- use parent element with ngIf, parent element can be any DOM element(div, etc..) or non-DOM elements like
ng-container
, and then use ngFor with a child element
ngIf inside ngfor in Angular with extra DOM element
In this example, created a separate Div element which is the parent element with the ngIf directive.
Added ngFor element inside div.
<h3>Multiple Directives in Same Elements</h3>
<button (click)="showTable()">Display Table!</button>
<div *ngIf="hide">
<div *ngFor="let employee of employees;">
<span>{{employee.name}}</span>
</div>
</div>
Output
As you see an extra DOM element is added which adds an extra element and breaks CSS style changes if you used a parent-child selector. It adds an extra DOM element for page rendering.
ng-container with ngIf and ngFor together
In this example, the ng-container helps us to group the local HTML elements which won’t add extra DOM elements and did not break the CSS change.
Solution is
- to use the
<ng-container>
element as a parent container with the ngIf directive. - Move the ngFor directive element inside the ng-container element
Here is an example
<h3>Multiple Directives in Same Elements</h3>
<button (click)="showTable()">Display Table!</button>
<ng-container *ngIf="hide">
<div *ngFor="let employee of employees;">
<span>{{employee.name}}</span>
</div>
</ng-container>
What is ng-container in Angular
ng-container
is a logical container to group HTML elements
- Logical group of DOM elements
- Does not add an extra element to DOM
- Multiple ng-container elements can be used.
- Output HTML will not produce any element
Conclusion
In Conclusion, ngSwitch
, and ngFor
is not combined with the ngIf
directive in Angular elements. The first solution is to add a parent DOM container HTML element with the ngIf directive with causes an extra DOM element node. The second solution is to use ng-container and don’t add extra DOM elements this approach is best to use