I would like to upload an array of files separately and then post other data only if the files are done. So far, each file uploads with its own request, but I can't make the other requests wait for the files to finish uploading - they all execute at the same time, despite the async/await.
Here is a simplified version of my code (where run()
needs to be an observable or promise and postOtherDatas()
needs to wait uploadFileList()
to be done):
public async run(data: Data): Promise<Object> {
await this.uploadFileList(data.files); // run this first
return this.postOtherDatas(data.otherData).subscribe(); // run this only if uploadFileList() is done
}
public async uploadFileList(files: File[]) {
return await Promise.all(files.map((file) => {
this.uploadFile(file).subscribe();
}));
}
public uploadFile(file: File): Observable<HttpEvent<any>> {
const req = new HttpRequest('POST', `apiUrl/postfile`,
formData, { withCredentials: true });
return this.http.request(req);
}
public postOtherDatas(formData: FormData) {
return this.http.post('apiUrl/postotherdata',
formData, { withCredentials: true }
);
}
I also tried this but postOtherDatas()
is never called:
public run(data: Data): Observable<Object> {
return this.uploadFileList(data.files).then(() => this.postOtherDatas(data.otherData).subscribe())
}
A rxjs subscription is not a promise:
public async uploadFileList(files: File[]) {
return await Promise.all(files.map((file) => {
// Not a promise!
this.uploadFile(file).subscribe();
}));
}
If you want to keep using promises, you can do it this way:
public async uploadFileList(files: File[]) {
return await Promise.all(files.map((file) => {
return this.uploadFile(file).toPromise();
}));
}
The same needs to be done in your run
method:
public async run(data: Data): Promise<Object> {
await this.uploadFileList(data.files); // run this first
return this.postOtherDatas(data.otherData).toPromise(); // run this only if uploadFileList() is done
}
However: I would propose you use rxjs more deliberately, it has some great tools for handling more complicated asynchronicity. E.g. Promise.all can be achieved using the forkJoin function.