I need to merge data from 4 different endpoints to create a ListElement that will be displayed in angular material table. I can see correct data in logs, but the table remains empty. If I add condition: "data.data.length > 0" it manages to show only 1 row, "data.data.length > 1" shows only 2 rows etc.
Constructor includes nested subscriptions which is probably not the best solution, but I'm not sure how to use forkJoin, mergeMap etc. when each subscription depends on the previous one.
This is component 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 is my html page:
<div *ngIf="!isLoading">
<table *ngIf="data" <------- If I add another condition: "data.data > 0" it shows only 1 row, "data.data > 1" shows only 2 etc.
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>