This is the archived documentation for Angular v6. Please visit angular.io to see documentation for the current version of Angular.

NgIf

Conditionally includes a template based on the value of an expression.

See more...

NgModule

Selectors

Properties

Property Description
@Input()
ngIf: any
Write-only.
@Input()
ngIfThen: TemplateRef<NgIfContext> | null
Write-only.
@Input()
ngIfElse: TemplateRef<NgIfContext> | null
Write-only.

Description

ngIf evaluates the expression and then renders the then or else template in its place when expression is truthy or falsy respectively. Typically the:

  • then template is the inline template of ngIf unless bound to a different value.
  • else template is blank unless it is bound.

Most common usage

The most common usage of the ngIf directive is to conditionally show the inline template as seen in this example:

@Component({ selector: 'ng-if-simple', template: ` <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button> show = {{show}} <br> <div *ngIf="show">Text to show</div> ` }) class NgIfSimple { show: boolean = true; }
      
      @Component({
  selector: 'ng-if-simple',
  template: `
    <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
    show = {{show}}
    <br>
    <div *ngIf="show">Text to show</div>
`
})
class NgIfSimple {
  show: boolean = true;
}
    

Showing an alternative template using else

If it is necessary to display a template when the expression is falsy use the else template binding as shown. Note that the else binding points to a <ng-template> labeled #elseBlock. The template can be defined anywhere in the component view but is typically placed right after ngIf for readability.

@Component({ selector: 'ng-if-else', template: ` <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button> show = {{show}} <br> <div *ngIf="show; else elseBlock">Text to show</div> <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template> ` }) class NgIfElse { show: boolean = true; }
      
      @Component({
  selector: 'ng-if-else',
  template: `
    <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
    show = {{show}}
    <br>
    <div *ngIf="show; else elseBlock">Text to show</div>
    <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
`
})
class NgIfElse {
  show: boolean = true;
}
    

Using non-inlined then template

Usually the then template is the inlined template of the ngIf, but it can be changed using a binding (just like else). Because then and else are bindings, the template references can change at runtime as shown in this example.

@Component({ selector: 'ng-if-then-else', template: ` <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button> <button (click)="switchPrimary()">Switch Primary</button> show = {{show}} <br> <div *ngIf="show; then thenBlock; else elseBlock">this is ignored</div> <ng-template #primaryBlock>Primary text to show</ng-template> <ng-template #secondaryBlock>Secondary text to show</ng-template> <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template> ` }) class NgIfThenElse implements OnInit { thenBlock: TemplateRef<any>|null = null; show: boolean = true; @ViewChild('primaryBlock') primaryBlock: TemplateRef<any>|null = null; @ViewChild('secondaryBlock') secondaryBlock: TemplateRef<any>|null = null; switchPrimary() { this.thenBlock = this.thenBlock === this.primaryBlock ? this.secondaryBlock : this.primaryBlock; } ngOnInit() { this.thenBlock = this.primaryBlock; } }
      
      @Component({
  selector: 'ng-if-then-else',
  template: `
    <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
    <button (click)="switchPrimary()">Switch Primary</button>
    show = {{show}}
    <br>
    <div *ngIf="show; then thenBlock; else elseBlock">this is ignored</div>
    <ng-template #primaryBlock>Primary text to show</ng-template>
    <ng-template #secondaryBlock>Secondary text to show</ng-template>
    <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
`
})
class NgIfThenElse implements OnInit {
  thenBlock: TemplateRef<any>|null = null;
  show: boolean = true;

  @ViewChild('primaryBlock')
  primaryBlock: TemplateRef<any>|null = null;
  @ViewChild('secondaryBlock')
  secondaryBlock: TemplateRef<any>|null = null;

  switchPrimary() {
    this.thenBlock = this.thenBlock === this.primaryBlock ? this.secondaryBlock : this.primaryBlock;
  }

  ngOnInit() { this.thenBlock = this.primaryBlock; }
}
    

Storing conditional result in a variable

A common pattern is that we need to show a set of properties from the same object. If the object is undefined, then we have to use the safe-traversal-operator ?. to guard against dereferencing a null value. This is especially the case when waiting on async data such as when using the async pipe as shown in following example:

Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
      
      Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
    

There are several inefficiencies in the above example:

  • We create multiple subscriptions on userStream. One for each async pipe, or two in the example above.
  • We cannot display an alternative screen while waiting for the data to arrive asynchronously.
  • We have to use the safe-traversal-operator ?. to access properties, which is cumbersome.
  • We have to place the async pipe in parenthesis.

A better way to do this is to use ngIf and store the result of the condition in a local variable as shown in the the example below:

@Component({ selector: 'ng-if-let', template: ` <button (click)="nextUser()">Next User</button> <br> <div *ngIf="userObservable | async as user; else loading"> Hello {{user.last}}, {{user.first}}! </div> <ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template> ` }) class NgIfAs { userObservable = new Subject<{first: string, last: string}>(); first = ['John', 'Mike', 'Mary', 'Bob']; firstIndex = 0; last = ['Smith', 'Novotny', 'Angular']; lastIndex = 0; nextUser() { let first = this.first[this.firstIndex++]; if (this.firstIndex >= this.first.length) this.firstIndex = 0; let last = this.last[this.lastIndex++]; if (this.lastIndex >= this.last.length) this.lastIndex = 0; this.userObservable.next({first, last}); } }
      
      @Component({
  selector: 'ng-if-let',
  template: `
    <button (click)="nextUser()">Next User</button>
    <br>
    <div *ngIf="userObservable | async as user; else loading">
      Hello {{user.last}}, {{user.first}}!
    </div>
    <ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template>
`
})
class NgIfAs {
  userObservable = new Subject<{first: string, last: string}>();
  first = ['John', 'Mike', 'Mary', 'Bob'];
  firstIndex = 0;
  last = ['Smith', 'Novotny', 'Angular'];
  lastIndex = 0;

  nextUser() {
    let first = this.first[this.firstIndex++];
    if (this.firstIndex >= this.first.length) this.firstIndex = 0;
    let last = this.last[this.lastIndex++];
    if (this.lastIndex >= this.last.length) this.lastIndex = 0;
    this.userObservable.next({first, last});
  }
}
    

Notice that:

  • We use only one async pipe and hence only one subscription gets created.
  • ngIf stores the result of the userStream|async in the local variable user.
  • The local user can then be bound repeatedly in a more efficient way.
  • No need to use the safe-traversal-operator ?. to access properties as ngIf will only display the data if userStream returns a value.
  • We can display an alternative template while waiting for the data.

Syntax

Simple form:

  • <div *ngIf="condition">...</div>
  • <ng-template [ngIf]="condition"><div>...</div></ng-template>

Form with an else block:

<div *ngIf="condition; else elseBlock">...</div> <ng-template #elseBlock>...</ng-template>
      
      <div *ngIf="condition; else elseBlock">...</div>
<ng-template #elseBlock>...</ng-template>
    

Form with a then and else block:

<div *ngIf="condition; then thenBlock else elseBlock"></div> <ng-template #thenBlock>...</ng-template> <ng-template #elseBlock>...</ng-template>
      
      <div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>...</ng-template>
<ng-template #elseBlock>...</ng-template>
    

Form with storing the value locally:

<div *ngIf="condition as value; else elseBlock">{{value}}</div> <ng-template #elseBlock>...</ng-template>
      
      <div *ngIf="condition as value; else elseBlock">{{value}}</div>
<ng-template #elseBlock>...</ng-template>