I am trying to list doctors with some specialization. But the code below is creating several title with item of same specialization.
Below is my html code:
<div class="row">
<div class="col-md-9" *ngFor="let doctor of doctors; let i = index">
<h3 class="header-subtitle">{{doctor.doctorSpeciality}}</h3>
<div class="doctor">
<div class="doctor-description">
<h4 class="name-title">Dr. {{ doctor.doctorName}}</h4>
</div>
</div>
<hr>
</div>
</div>
The output I am getting is like:
doctor name1
doctor name2
doctor name3
Here, the doctor name3 of category general physician should be under heading of first header title.
This is not something that you can achieve only in html (without some directives/pipes at least).
I don't know exactly how you .ts code looks like, but the grouping you're seeking for needs to be made on the actual collection that you're using inside *ngFor. Most likely doctors
is a flat array of objects, something like below, on which you can use reduce
and map
for computing the groups.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
readonly doctors = [
{
doctorSpeciality: 'General Physician',
doctorName: 'doctor name 1'
},
{
doctorSpeciality: 'Cardiologist',
doctorName: 'doctor name 2'
},
{
doctorSpeciality: 'General Physician',
doctorName: 'doctor name 3'
}
];
specialityGroupedDoctors = {};
constructor() {
this.computeGroups();
}
private computeGroups(): any {
this.specialityGroupedDoctors = this.doctors.reduce(
(acc: any, doc: any) => {
if (!acc[doc.doctorSpeciality]) {
acc[doc.doctorSpeciality] = [];
}
acc[doc.doctorSpeciality].push(doc);
return acc;
}, {});
}
}
And then the html template needs to change to this:
<div class="row">
<div class="col-md-9" *ngFor="let group of specialityGroupedDoctors | keyvalue">
<h3 class="header-subtitle">{{group.key}}</h3>
<div class="doctor" *ngFor="let doctor of group.value">
<div class="doctor-description">
<h4 class="name-title">Dr. {{ doctor.doctorName}}</h4>
</div>
</div>
<hr>
</div>
</div>
Here you have a StackBlitz sandbox where you can see it working: https://stackblitz.com/edit/angular-ivy-t86wnc?file=src/app/app.component.html