Let´s assume, we are downloading file using HTTP POST method. We want to call another method to show download progress to end user until file download complete. How to use reportProgress in HttpClient for this?

Solution:

  1. We need to use reportProgress: true to show some progress of any HTTP request
  2. If we want to see all events, including the progress of transferts , we need to use observe: 'events' option as well and return an Observable of type HttpEvent.
  3. Then we can catch all the events(DownloadProgress, Response..etc) in the component method.
 downfile(file: any): Observable<HttpEvent<any>>{

    const options = {
        responseType: 'blob' as const,
        reportProgress: true, 
        observe: "events" as const,
        headers: new HttpHeaders({ 'Content-Type': 'application/json' })
    };
  
    return this.http.post(this.url , app, options);
  }

Then in component we can catch all the events as below.

this.myService.downfile(file)
    .subscribe(event => {

        if (event.type === HttpEventType.DownloadProgress) {

           const percentDone = Math.round(100 * event.loaded / event.total);
            console.log("download in progress ====> " + percentDone + "%");
        }

        if (event.type === HttpEventType.Response) {
            console.log("donwload completed");
        }
});

PS-1:  there are different kinds of HttpEvent.

enum HttpEventType {
  Sent
  UploadProgress
  ResponseHeader
  DownloadProgress
  Response
  User
}

PS-2 : (OBSERVE AND RESPONSE TYPES) ==> The types of the observe and response options are string unions, rather than plain strings.

options: {
  …
  observe?: 'body' | 'events' | 'response',
  …
  responseType?: 'arraybuffer'|'blob'|'json'|'text',
  …
}

This can cause confusion. For example:

// this works
client.get('/foo', {responseType: 'text'})

// but this does NOT work
const options = {
  responseType: 'text',
};
client.get('/foo', options)

In the second case, TypeScript infers the type of options to be {responseType: string}. The type is too wide to pass to HttpClient.get which is expecting the type of responseType to be one of the specific strings. HttpClient is typed explicitly this way so that the compiler can report the correct return type based on the options you provided.

Use as const to let TypeScript know that you really do mean to use a constant string type:

const options = {
  responseType: 'text' as const,
};
client.get('/foo', options);

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *