Issue
I have a usecase as below: My objective is to update the array in if
and else
case.
The main array(cis) looks like below
.html
<sample-container [cis]="filterCi(currentBaseline.cis, currentBaseline)"> </sample-container>
.ts
This function runs a map over the array provided above and returns the same structure with all the objects execpt those with property checked:false
(removed from the structure) by doing a recursive call on children everytime.
//retrieveChildren
retreiveChildren(children: Structure[]) : Structure[] {
let filteredCis = children && children.filter((ci) =>{
if(ci.children && ci.children.length > 0){
retreiveChildren(ci.children);
}
return ci.checked === true;
}) ;
return filteredCis;
}
//filterCi function
filterCi(cis: Structure[], baseline: Baseline): Structure[] {
if(baseline.isHideElementsActivated){
let newArray = [...cis]
let result = newArray.filter(ci => ci.checked === true).map((item,index) => {
return {
...item,
children : retreiveChildren(item.children)
}
})
console.log("Result array...." , result)
return result;
}else{
return cis;
}
}
The issue I am facing here is, the filterCi
function is calling infinitely. Initially, I thought it is because of the recursive call, but even after removing recursion it results in infinite loop.
Finally, I could conclude that it is because of map
function used inside filterCi.
Why is this behavior and how can I resolve it?
Solution
As you are calling a method from an input binding in a template it will be evaluating on every change detection cycle, as angular has no way of knowing that this is a pure function (see: https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496).
I think this may be the problem you are seeing. To resolve you can use an angular pipe: https://angular.io/guide/pipes
Edit: You should be able to treat the transform method of the pipe as the filterCi method creating a pipe like:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterCis'
})
export class FilterCisPipe implements PipeTransform {
public transform(cis: Structure[], baseline: Baseline): Structure[] {
if(baseline.isHideElementsActivated){
let newArray = [...cis]
let result = newArray.filter(ci => ci.checked === true).map((item,index) => {
return {
...item,
children : retreiveChildren(item.children)
}
})
console.log("Result array...." , result)
return result;
}else{
return cis;
}
}
private retreiveChildren(children: Structure[]) : Structure[] {
let filteredCis = children && children.filter((ci) =>{
if(ci.children && ci.children.length > 0){
retreiveChildren(ci.children);
}
return ci.checked === true;
}) ;
return filteredCis;
}
}
Then after registering the pipe in the app module. Use it in the template like:
<sample-container [cis]="currentBaseline.cis | filterCi:currentBaseline"> </sample-container>
Answered By - Jonathan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.