Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 *ngIf="afunctioncall()" results in the function being called 9 times

I am working with Angular2 and want an element to conditionally display based upon the result of a function call.

When I do this I've noticed that the function is called multiple times.

@Component({
  selector: 'my-app',
  template: `
    <h1>Hello</h1>
    <div *ngIf="returnsTrue()">
       <h1>World</h1>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }

    returnsTrue(): boolean {
        console.log('Returning true');
        return true;
    }
}

See associated plnkr:

http://plnkr.co/edit/MScwD3LaIj9YfBlwWltw?p=preview

The 'Returning true' console.log is output 4 times.

Can anyone point me as to why this occurs?

And is there anyway to avoid it?

I've seen the following post however with it being related to Angular 1 and the digest cycle being re-written for Angular2 I'm not sure it's relevant:

ng-if being called more times than it should

like image 313
SamF Avatar asked Oct 04 '16 10:10

SamF


People also ask

What is the use of * ngIf in angular2?

A shorthand form of the directive, *ngIf="condition" , is generally used, provided as an attribute of the anchor element for the inserted template. Angular expands this into a more explicit version, in which the anchor element is contained in an <ng-template> element.

How do you check for equal conditions in ngIf?

Use double equal to == operator to check equality or better use === to check strict equality. You should use === in Javascript instead.

What is the difference between * ngIf and ngIf?

What is the difference between ngIf and *ngIf in Angular? ngIf is the directive. Because it's a structural directive (template-based), you need to use the * prefix to use it into templates. *ngIf corresponds to the shortcut for the following syntax (“syntactic sugar”):

What type of expressions can ngIf accept?

The ngIf directive can take as input any valid Typescript expression and not just a boolean.


1 Answers

I suspect that your function is called on every change detection cycle, particularly in dev mode when Angular is checking the expression in the *ngIf for changes multiple times, and in doing so is calling the function.

One way to avoid it would be to change a class variable in your function, and monitor that variable in your *ngIf:

@Component({
  selector: 'my-app',
  template: `
    <h1>Hello</h1>
    <div *ngIf="isTrue">
       <h1>World</h1>
    </div>
  `,
})
export class App {
  name:string;
  isTrue:boolean = false;
  constructor() {
    this.name = 'Angular2'

    setTimeout(() => {
      this.returnsTrue();
    }, 5000);

  }

    returnsTrue(): boolean {
        console.log('Returning true');
        this.isTrue = true;
    }
}

I adapted your Plunker to show this.

like image 76
Harry Avatar answered Dec 02 '22 02:12

Harry