2

I have a table where each row has been created using ngFor

 <tbody>
    <tr *ngFor="let item of Details">
        <div class="row details-row row-cols-lg-2 row-cols-1" *ngIf="closureDetails">
            <div class="col" [ngClass]="{'d-none':getMilestones(item.ProjectCode)?.length===0}">
                <app-milestone [milestones]="getMilestones(item.ProjectCode)"></app-milestone>
            </div>
            <div class="col" [ngClass]="{'d-none':getRisks(item.ProjectCode)?.length===0}">
                <app-risk [risks]="getRisks(item.ProjectCode)"></app-risk>
            </div>
        </div>
    </tr>
</tbody>

Here as you can see I am setting the class for cols using the same function for passing data to the child component. But my concern is the function fires twice and for the first time its just for toggling the visibility of the DIV.COL

When there are 300+ rows which costs 600 hits for the same function which causing some delay in process.

So please suggest a good approach to optimise this requirement

4
  • 2
    First of all, Why you should never use function calls in Angular template expressions Commented Oct 25, 2021 at 8:34
  • 1
    "function fires twice" - are you sure it's only firing twice? Binding functions to directives and properties with default change detection strategy would trigger the function for each change detection cycle. In other words, possibly too many times than you think it does. Commented Oct 25, 2021 at 8:38
  • It definitely will trigger more than twice. Commented Oct 25, 2021 at 8:44
  • 1
    @MichaelD You are absolutely right.. I verified the hit count and its more than 2. I had no idea.. I am a beginner with Angular Commented Oct 25, 2021 at 9:21

1 Answer 1

1

Like @ricky said, you should never use function calls in template expressions

Solution: (Choose Milestone things as an sample)

Introduce variables in the component, and use it the template to replace the function bindings:

`hasMileStones` for `getMilestones(item.ProjectCode)?.length===0}`

`projectCodeToMileStonesMap[item.ProjectCode]` for `getMilestones(item.ProjectCode)`

Template:

<div class="col" [ngClass]="{'d-none':!hasMileStones}">
    <app-milestone [milestones]="projectCodeToMileStonesMap[item.ProjectCode]"></app-milestone>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. projectCodeToMileStonesMap is an array variable, isnt it?
it could be an Object, depend on how your data structure is. if data structure: {projectCode: mileStoneObj}, it could be an Object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.