My challenge is to consolidate data from 4 different endpoints in order to generate a ListElement that will populate an angular material table. Despite receiving the correct data in my logs, the table remains empty. Interestingly, when I include a condition like "data.data.length > 0", only one row is displayed; "data.data.length > 1" results in two rows being shown.
The constructor currently contains nested subscriptions which might not be the most efficient approach. I'm uncertain how to utilize forkJoin and mergeMap effectively when each subscription relies on the previous one.
This snippet showcases the component's constructor:
constructor(injected services...) {
this.userId = this.tokenStorageService.getCurrentUserId();
this.isLoading = true;
let getAllBookingsParams = new GetAllBookingsParams();
getAllBookingsParams.userId = this.userId;
this.bookingsService
.getAll(getAllBookingsParams)
.toPromise()
.then((bookings) => {
let permData = [];
bookings.forEach((booking) => {
this.propertiesService
.get(booking.propertyId)
.subscribe((property) => {
this.citiesService.get(property.cityId).subscribe((city) => {
this.propertyImagesService
.getAll(property.id)
.subscribe((images) => {
let listElement = new BookingsListElement();
# initialize listElement with data from above
permData.push(listElement);
});
});
});
});
this.data = new MatTableDataSource(permData);
this.data.data = permData;
console.log(this.data);
this.isLoading = false;
});
}
This section outlines the corresponding HTML page:
<div *ngIf="!isLoading">
<table *ngIf="data" <------- By adding another condition: "data.data > 0", only 1 row appears; ""data.data > 1" shows 2 rows.
mat-table
[dataSource]="data"
multiTemplateDataRows
class="mat-elevation-z8">
<ng-container
matColumnDef="{{ column }}"
*ngFor="let column of columnsToDisplay"
>
<th mat-header-cell *matHeaderCellDef>{{ column }}</th>
<td mat-cell *matCellDef="let element">{{ element[column] }}</td>
</ng-container>
<ng-container matColumnDef="expandedDetail">
<td
mat-cell
*matCellDef="let element"
[attr.colspan]="columnsToDisplay.length"
>
<div
class="example-element-detail"
[@detailExpand]="
element == expandedElement ? 'expanded' : 'collapsed'
"
>
<div class="example-element-diagram">
<div *ngIf="element.imageUrl" class="example-element-image">
<img [src]="element.imageUrl" />
</div>
</div>
<div class="example-element-content">
<div class="example-element-description">
{{ element.propertyName }}
</div>
<div class="example-element-description">
<span class="example-element-description-attribution"
>{{ element.address }}, {{ element.city }}</span
>
</div>
<div class="example-element-description">
{{ element.description }}
</div>
<div class="example-element-description">
Accommodates number:
{{ element.accommodatesNumber }}
</div>
<div class="example-element-description">
Bathroom number:
{{ element.bathroomNumber }}
</div>
<div class="example-element-description">
Bedroom number:
{{ element.bedroomNumber }}
</div>
</div>
<div class="example-element-diagram">
<button
mat-raised-button
color="primary"
[routerLink]="['/properties/details', element.propertyId]"
>
Property details
</button>
<br />
<button
*ngIf="!element.cancellationDate"
mat-raised-button
color="warn"
(click)="cancelBooking(element.id)"
>
Cancel booking
</button>
<br />
<button
*ngIf="element.cancellationDate"
mat-raised-button
color="warn"
disabled
>
Booking cancelled {{ element.cancellationDate | date }}
</button>
</div>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr
mat-row
*matRowDef="let element; columns: columnsToDisplay"
class="example-element-row"
[class.example-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element"
></tr>
<tr
mat-row
*matRowDef="let row; columns: ['expandedDetail']"
class="example-detail-row"
></tr>