I am using HttpInterceptor
and I have an Http service that calls http methods running HttpClient. I am trying to get the progress of the upload and I am facing two issues here,
First, progress event is only being caught by HttpInterceptor
and not any of my Http caller methods in my service. it looks like the former is masking the progress reporting.
Second, The progress value always starts with 100%, and the it starts the increment.
I am lazily loading my module, HttpInterceptor is registered at the app.module level.
How can I get the progress value from an http method?
my HttpInterceptor
service looks like,
if (req.url.search('https') < 0) {
const headers = new HttpHeaders({
Accept: 'application/json',
Authorization: `Bearer ${this.authService.getToken()}`,
'X-XSRF-TOKEN': `${this.authService.getAntiforgeryToken()}`,
ClientTimeZoneOffest: `${new Date().getTimezoneOffset()}`,
ClientTimeZoneId: Intl.DateTimeFormat().resolvedOptions().timeZone,
ClinetLogInId: `${this.authService.getLogInId()}`,
});
const cloneReq = req.clone({ headers });
return next.handle(cloneReq).pipe(
mergeMap((ev: HttpEvent<any>) => {
if (ev.type === HttpEventType.UploadProgress) {
const percentDone = Math.round((100 * ev.loaded) / ev.total);
console.log(`File is ${percentDone}% uploaded.`);
}
this.httpResponseHandlerService.handleSuccessResponse(ev);
return Observable.of(ev);
}),
catchError(error => {
this.httpResponseHandlerService.handleErrorResponse(error, req);
return Observable.throw(error);
}),
);
} else {
return next.handle(req);
}
}
my Http caller service,
public upload<T>(apiUrl: string, jsonData: {} = {}) {
return this.httpService.post<T>(this.baseUrl + apiUrl, jsonData, {
reportProgress: true,
});
}
and the method where I am trying to get the progress in is like,
this.httpService
.upload(this.api + this.id.value, data)
.takeUntil(this.unsubscribe)
.subscribe((ev: HttpEvent<any>) => { // Nothing is happening here!
if (ev.type === HttpEventType.UploadProgress) {
const percentDone = Math.round((100 * ev.loaded) / ev.total);
console.log(`File is ${percentDone}% uploaded.`);
}
});
The progress behavior is,
The way you're performing the request is incorrect, please refer to http://angular.io/guide/http#listening-to-progress-events
You should create an HttpRequest
then call this.http.request(req)
instead of this.http.post(...)
http.post
is just the short-hand for performing normal http request by http.request
. For full request creating options, like when we want to download or upload with progress tracking, you should go with the http.request
(where you manually create the request object with many options, then perform it).
Also quoted from the document:
// The
HttpClient.request
API produces a raw event stream// which includes start (sent), progress, and response events.
By the way, it's not a good practice to put the upload progress handling in the HttpInterceptor, as it's effect is project wide, i.e. every request you make you make will go through the interceptor. And you don't need the progress handling in every request, or do you?