Reputation: 83
I was exploring Pipe functions in Angular and got to know that for non-primitive data types like arrays , even if there is a change in the array's elements the pipe function would not apply to the updated array and would be applied for the initial array itself. That is why when we add new elements pipe functions are not added to these new elements of the array.
But when I tried deleting, adding and updating existing elements of an array with a pipe function it worked. However, the changes the array should not be reflected to the UI as the pipe funciton is a pure one. Please let me know why the changes of an array are being reflected when the pipe is pure.
pipe.TS:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'arrayPipe',
// pure:false
})
export class ArrayPipePipe implements PipeTransform {
transform(value: number[]) {
value.pop();
value.push(4);
value[1]=5;
console.log(value);
return (value);
}
}
app.HTML:
<div>{{trialArray}}</div>
<div>{{trialArray | arrayPipe }}</div>
app.component.TS:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
trialArray = [1,2,3];
}
Upvotes: 0
Views: 505
Reputation: 57939
question: When Angular know that "something" change?
answer: when his value change
The problem with arrays (and objects) are that not change when change some value (or some property) of it, else if change the "position in memory". This is the reason you need "create a new array". Generally you use the "spread operator"
this.trialArray=[...this.trialArray] //the ... are the spread operator
This is the reason because it's not a good aproach use pipe to transform an array (even a pipe sort)
In the stackblitz if you comment the line
this.trialArray=[...this.trialArray]
You can not see the array correctly
Of course you can create a pipe "impure". When you declare the pipe you write pure:false
@Pipe({
name: 'arrayPipe',pure:false //<--see the "pure:false"
})
export class ArrayPipe implements PipeTransform{
transform(value: any[], args?: any): any {
return value.map((x) => x * 2);
}
}
This makes that you can "change" the array (without create a copy) and show the result. But see that in this case the array in .html is not updated
<div>{{trialArray}}</div> //<--this show always [1,2,3]
<div>{{trialArray | arrayPipe }}</div> //<--this change when "click"
click(){
this.trialArray.push(4);
}
but this makes that "In this case, the pipe is invoked on each change-detection cycle, even if the arguments have not changed.", see the docs.
We can see adding a console.log("here") in the function transform
About the pipe in the question there're two problems
Change the value of the array. We can solve make a copy before (we can use the sprred operator
export class ArrayPipe implements PipeTransform {
transform(value: any[], args?: any): any {
const result=[...value] //make a copy
result.pop(); //change the copy
result.push(4);
result[1]=5;
return result
}
}
if we want we can convert the pipe to impure adding pure:false
when create
Upvotes: 1