Context
We have an offer view on the front end that looks like this:
<table>
<tbody>
<tr *ngFor="let offer of offerList">
<td>{{offer[0].appArea.creationDate}}</td>
<td>{{offer[0].client.id}}</td>
<td>{{offer[0].client.name}}</td>
...
</tr>
</tbody>
</table>
This offerlist
is collected from a database in a less traditional way : only the ids and a hash are stored in the database, with which an IPFS network is accessed, which is the one that has the data of the offers.
In addition, it is set up in such a way that, to obtain an array of n
offers, exactly n + 1
requests are made: the first one brings the array with the ids and hash, and the n
following ones are the result of iterating through that array and asking the IPFS for the data:
export class OffersComponent implements OnInit{
offerList: Array<any> = []
loadOffersForClient(email) {
this.offerService.getOwnerInitialOffers(email).subscribe(
(initOfferResponse) => {
initOfferResponse[0].offers.map((item) => {
this.offerService.getOfferFileData(item.hashId).subscribe(
(itemResponse) => {
this.offerList.push([itemResponse, item, ]);
}
);
});
}
);
}
}
The service makes simple calls with the http client:
export class OfferService {
constructor(private http: HttpClient) { }
getOwnerInitialOffers(email: string) {
return this.http.post<any>(`path/to/offers/${email}`); // se traen datos por post porque asi esta especificada la api
}
getOfferFileData(hashId: string) {
return this.http.get<any>(`path/to/file/server/${hashId}`);
}
}
Problem
The requirements have changed and we need to order the array. By date, to be more exact. The problem comes from the fact that I am not sure when I can order the array being sure that the elements have finished filling .
Until now, it had occurred to me to order it by brute force, every time a new request is launched:
this.offerService.getOfferFileData(item.hashId).subscribe(
(itemResponse) => {
this.offerList.push([itemResponse, item, ]);
this.offerList.sort((a, b) => {
const firstDate = a[0].applicationArea.creationDateTime;
const secondDate = b[0].applicationArea.creationDateTime;
return (firstDate < secondDate) ? 1 : ((firstDate > secondDate) ? -1 : 0);
});
}
);
Aside from being incredibly inefficient, it doesn't work, I understand that the items haven't been loaded by the time the sort occurs.
How can I make sure that the array has already been loaded, so that I can sort only once and without the danger of new elements entering?
You can use the RxJs function
forkJoin
:Working example: