Search code examples
angularangular-directivengforangular-template

ngFor to iterate an array of objects and count the length of an array property


I'm doing a web application in Angular 6. I receives an array of objects from Firebase and I'm trying to show the details to the user using ngFor. My array of objects is like this:

export interface Competition {
  createdAt: Date;
  sessions: Session[];
}

export interface Session {
  date: Date;
  program: Program[];
  events: Event[];
}

export interface Program {
  name: string;
}

export interface Event {
  name: string;
}

Inside the template I am doing:

<ng-container *ngFor="let competition of competitions; index as i">
   <h3>{{competition.name}}</h3>
   {{competition.sessions[i].program.length}}
   {{competition.sessions[i].events.length}}
</ng-container>

read property 'program' of undefined, read property 'events' of undefined

I have tried:

{{competition[i].sessions[i].program.length}}
{{competition.sessions[i].program.length}}
{{competition[i].sessions[i].program[i].length}}

My goal is to show the length of program and events.


Solution

  • You iterate over competitions array but try to get competition.sessions[i]. You need something like this:

    <ng-container *ngFor="let competition of competitions; index as i">
       <h3>{{competition.name}}</h3>
       <div *ngFor="let session of competition.sessions">
          {{session.program.length}}
          {{session.events.length}}
       </div>
    </ng-container>
    

    If you want to get the total number of sessions and event for a competition, you should count them in your ts file

    this.competitionResults = this.competitions
       .map(competition => competition.sessions
           .reduce((res, session) => 
               ({
                    programLength: res.programLength + session.program.length, 
                    eventLength: res.eventLength + session.events.length,
               }), {
                    programLength: 0, 
                    eventLength: 0,
               }))
       )
    

    And HTML:

    <ng-container *ngFor="let competitionResult of competitionResults">
       {{ competitionResult.programLength }}
       {{ competitionResult.eventLength}}
    </ng-container>