36

I am trying to render object properties using keys in angular2 using below code:

<ul>
    <li *ngFor="let element of componentModel | keys;let i=index">
      {{element.key}}--{{element.value}}  // 1---Bhushan...loaded only once
      <span  *ngIf="element">{{ loadProperty(i,element) }}</span>
    </li>
</ul>

But I am facing a problem here. The output in the browser in loaded only once. but the method call i.e. loadProperty(i,element) is running in an infinite loop.

loadProperty(i:number,element:any){       
    console.log(element.key+'========'+element.value);
    console.log(element);      
}

means on browser output

(1---Bhushan)

is displayed only once but on the console its running infinitely like below:

Snapshot of the console

I want to call this method only once per iteration.

any inputs?

Bhushan Gadekar
  • 13,485
  • 21
  • 82
  • 131

1 Answers1

35

This is just Angular2 change detection at work calling loadProperty(i,element) over and over in each change detection cycle.

Calling methods from the template is discouraged because they are called very often. You should instead store the result in a property and bind to this property instead.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I am not sure how to do this with property binding, do u have any plnkr for this where method will get called only once per iteration? @Gunter – Bhushan Gadekar Jun 17 '16 at 08:25
  • What are you trying to accomplish? Sounds like http://stackoverflow.com/questions/36427670/angular2-calling-custom-function-after-ngswitch-new-view-is-created/36427769#36427769 – Günter Zöchbauer Jun 17 '16 at 08:28
  • 1
    pretty much same but I also want to pass the iterated element to the method. actually these elements are objects and I am providing an editor for each element based on its type to change its value. ie. if it's an object consisting of arrays then it will load objectEditorComponent & inside that it will load arrayEditorComponent for each array. thus I use *ngFor to iterate and pass iterated element to function to select correct editor based on its datatype. its a recursive process until it gets the last element. – Bhushan Gadekar Jun 17 '16 at 08:34
  • What part exactly is causing you troubles? – Günter Zöchbauer Jun 17 '16 at 08:41
  • the one I mentioned in the question. the function is getting called for multiple times though I want it to get called only once per iteration – Bhushan Gadekar Jun 17 '16 at 08:42
  • 3
    That's exactly what the directive in the linked answer is supposed to do. `` should do what you want. – Günter Zöchbauer Jun 17 '16 at 08:48
  • i have got this error `Generic type 'EventEmitter' requires 1 type argument(s)` – Bhushan Gadekar Jun 17 '16 at 09:16
  • That's caused by the static checks in your IDE. Just use the type you want to pass. In my example it emits `"dummy"` which would require `@Output() someOutput:EventEmitter = new EventEmitter();` – Günter Zöchbauer Jun 17 '16 at 09:26