I have working solution to getting download progress in Angular 13 / RxJs 7.
First I defined some enums:
export enum RequestType {
get = 'GET',
post = 'POST',
put = 'PUT',
delete = 'DELETE',
}
export enum ActionType {
download = 1,
upload
}
Next, I implemented a shared service to handle tracking progress:
@Injectable({
providedIn: 'root'
})
export class DownloadProgressService {
percentDone = 0;
actionType: ActionType;
constructor(private http: HttpClient) { }
downloadFile(uri: string, requestType: RequestType, actionType: ActionType, body: any): Observable<number> {
this.actionType = actionType;
const req = new HttpRequest(requestType, uri, body, {
reportProgress: true,
responseType: 'blob'
});
return this.http
.request(req)
.pipe(
map(event => this.getPercentage(event)),
);
}
public getPercentage(event: HttpEvent<any>): number {
switch (event.type) {
case HttpEventType.UploadProgress:
// Downloading files will still trigger upload progress due to the back-and-forth, ignore this
if (this.actionType !== ActionType.upload) {
return 0;
}
// Compute and show the % done:
if (event && event.total) {
this.percentDone = Math.round(100 * event.loaded / event.total);
return this.percentDone;
} else {
return 0;
}
case HttpEventType.DownloadProgress:
if (event && event.total) {
this.percentDone = Math.round(100 * event.loaded / event.total);
}
return this.percentDone;
default:
// Not an event we care about
return this.percentDone;
}
}
}
Then, I simply subscribe to this and get proper progress of the download:
this.downloadService
.downloadFile(url, RequestType.post, ActionType.download, body)
.subscribe(progress => this.progress = progress);
This all works great, I get a progress bar with my component library that shows real progress.
The question is ... how do I get the resulting file?
Instead of returning only the progress you could return an object that contains the progress percentage and the HTTP response.
Now in the subscription you can you use the object