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
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.
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 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”):
The ngIf directive can take as input any valid Typescript expression and not just a boolean.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With