Home > Back-end >  show 1 data instead of all ngFor - Angular 11
show 1 data instead of all ngFor - Angular 11

Time:08-03

Im trying to display total counts of enrollment with item.male_students & item.female_students

UPDATE
remove the ngFor now it works as expected. here's my component.html

<thead >
    <tr>
        <th>
            Total Enrollment Quick Count
        </th>
    </tr>
</thead>
<tbody >
    <tr>
        <td>
            {{ item.male_students   item.female_students }}
        </td>
    </tr>
</tbody>

UPDATED
here's my component.ts

data: []; 

  constructor(private apiService: ApiService) {
    super();
  }

  ngOnInit(): void {
    this.getEnrollMentCountBySex();
  }

  getEnrollMentCountBySex() {
    this.apiService.getAll('enrollments', "/count-student-enrollment-by-sex-and-academic-level")
    .subscribe(data => {
      this.data = data;
      this.maleCount = data.reduce(((acc, item) => acc   item.male_students), 0);
      this.femaleCount = data.reduce(((acc, item) => acc   item.female_students), 0);
    });
  }

Im getting object. Here's and image from api endpoint

enter image description here

UPDATE
But im getting all the index. I only want the total count of male & female students to be shown in table

enter image description here

CodePudding user response:

You can do it as soon as you receive data from ajax. That's the good way I would suggest you in this case.

getEnrollMentCountBySex() {
   this.apiService.getAll('enrollments', "/count-student-enrollment-by-sex-and-academic-level").subscribe(data => {
      this.data = data;
      this.maleCount = data.reduce((acc, item) => acc   item.male_students), 0);
      this.femaleCount = data.reduce((acc, item) => acc   item.female_students), 0);
   });
}

HTML

Male Count - {{ maleCount }}
Female Count - {{ femaleCount }}

If data is being modified from user in your case and we wanted to keep UI bindings updated. Then definitely using Pipe or function call on binding would be a better idea.

@Pipe({name: 'countByProp'})
export class CountByPropPipe implements PipeTransform {
  transform(data: any, prop: string): number {
    if (!prop) throw new Error('Please pass property name');
    return data.reduce((acc, item) => acc   item[prop]), 0);
  }
}

HTML

Male Count - {{ data | countByProp: 'male_students' }}
Female Count - {{ data | countByProp: 'female_students' }}

TS

Define maleCount and femaleCount variable in your HomePage.ts

maleCount = 0;
femaleCount = 0;

CodePudding user response:

I wrote a slightly different approach. (though I would also prefer using pipes). Here we use | async pipe which takes care of unsubscribe and using tap we create a sideeffect and calculate totals of from the data.

<tbody >
    <tr *ngFor="let item of data$ | async; let i = index">
        <td>
            {{ item.male_students   item.female_students }}
        </td>
    </tr>
    total males: {{totalMaleStudents}}
   total females: {{totalFemaleStudents}}
</tbody>
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  data$: any;
  totalFemaleStudents = 0;
  totalMaleStudents = 0;

  ngOnInit() {
    const apiData = [
      { name: 'elementary', id: 1, female_students: 1, male_students: 1 },
      { name: 'highschool', id: 2, female_students: 0, male_students: 0 },
      { name: 'junior', id: 3, female_students: 0, male_students: 0 },
    ];

    // mock
    this.data$ = of(apiData).pipe(
      tap((data) => {
        console.log(data);
        
        // validate
        if (!Array.isArray(data)) {
          return;
        }

        // calculate
        for (let i = 0; i < data.length - 1; i  ) {
          if (data[i]?.female_students) {
            this.totalFemaleStudents  = data[i]?.female_students;
          }
          if (data[i]?.male_students) {
            this.totalMaleStudents  = data[i]?.male_students;
          }
        }
      })
    );
  }
}

Working example: https://stackblitz.com/edit/angular-ivy-nvw55f?file=src/app/app.component.ts

  • Related