1

I have the template view like this.

<p [innerHTML]="myfunction()"></p>

and, ts file be like

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  myfunction(){
    alert(name);
    return '<div>abcd</div>';

  }
}

Its a simple method calling from html to render the html content through innerhtml, here the myfunction() is calling multiple times, and i'm getting multiple alerts, can anyone help me to solve this.

the stackblitz for this is link

thanks in advance

saran
  • 75
  • 3
  • 13
  • 1
    It's normal behavior: during the display cycle Angular will "recheck" the state of everything in case it changed since last step. Better to not call functions and instead put the value in a property. If the computation can be complex, call it within `ngOnInit` and store the result in a property, and display said property in the template. Not posting this as an answer since I'm not sure whether you're asking "why" this happens or if there's a workaround. – Jeto Mar 14 '19 at 11:57
  • It is called multiple times because it called on every application tick, it's impossible for angular to detect if your method is idempotent. – Dariusz Ostolski Mar 14 '19 at 11:58
  • I got to know, angular will recheck the state multiple time, in my project, i'm rending input element through innerHtml, when i type something in the input box, again its calling the same method , i need to get the value entered in the input element, this html i'm getting from server call , so i can't hardcode –  saran Mar 14 '19 at 12:09

1 Answers1

3

You can use pure pipe to only rerun it if inputs to the pipe have changed:

@Pipe({name: 'functionCaller'})
export class FunctionCallerPipe {
    transform(func: any, ...args: any[]): any {
        return func(...args);
    }
}

And use it like that:

<p [innerHTML]="myfunction| functionCaller : name"></p>
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  myfunction(name: string){
    alert(name);
    return '<div>' + name + '</div>';
  }
}
waterplea
  • 3,462
  • 5
  • 31
  • 47