Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Array.map in Angular Interpolation

Using Angular 2+, how can I do something like bellow in the HTML?

{{ object.array.map( (o)=> o.property ) }}

This code crashes the angular application. I have to use Pipe or something like that?

like image 913
Victor Soares Avatar asked Jul 18 '19 18:07

Victor Soares


2 Answers

You can't define functions in Angular expressions. So you have to use pipes instead which are optimized for the templates. They are reusable across other components.

<pre>{{ object.array | pluck:"property" | json }}</pre>

With a pluck pipe:

@Pipe({name: 'pluck'})
export class PluckPipe implements PipeTransform {
  transform (input: any[], key: string): any {
      return input.map(value => value[key]);
  }
}

It's not recommended to call functions on the component to calculate values for the template. This moves work from the component to the template, and if you need data to be mutated then do that work in ngOnInit() or in ngOnChanges() instead.

Pipes have purity which means they are executed only when the inbound data is mutated. When you call a function like {{doWork(object.array)}} then Angular does not know if the function doWork() is pure or not. So it assumes it is not pure and calls it for each change detection.

Updated:

Anytime you work with Arrays in Angular you should be treating them as immutable. Where you create a new instance of that Array when you need to modify it. For example; items = [...items, newItem]; instead of items.push(newItems).

This resolves change detection problems related to pipes, ngFor, OnPush change detection and state stores.

https://medium.com/dailyjs/the-state-of-immutability-169d2cd11310

like image 179
Reactgular Avatar answered Sep 21 '22 01:09

Reactgular


you could find some work around's to make this work, but my answer is you shouldn't do this as function calls in template negatively impact performance, as do impure pipes which this would require to be reliable.

Consider instead:

mappedArray = [];

ngOnInit() {
  this.mappedArray = object.array.map( (o)=> o.property );
}

{{ mappedArray }}

clean, reliable, easy to read / modify and easy to understand. Also gives more fine tuned control over when your functions evaluate.

like image 44
bryan60 Avatar answered Sep 19 '22 01:09

bryan60