HttpRequest and reportProgress not working or messing up my requests
Solution 1
I solved the issues. There were actually two things that were involved in the behavior described in the question.
First of all ... rtfm! https://angular.io/api/common/http/HttpClient
This method [HttpClient.request()] can be called in one of two ways. Either an HttpRequest instance can be passed directly as the only parameter, or a method can be passed as the first parameter, a string URL as the second, and an options hash as the third.
If a HttpRequest object is passed directly, an Observable of the raw HttpEvent stream will be returned.
This explains why my two request (both passed as HttpRequest
returned {type: 0}
from now on, regardless of the reportProgress
-paramter being true
or false
.
Only receiving the SENT-event ({type: 0}
) on the other hand was a missconfiguration of the backend itself.
Solution 2
along with {reportProgress: true} you would need to send {observe: 'events'}
this.httpClient.post(environment.uploadDocument, file, { reportProgress: true, observe: 'events' })
.subcribe(data =>{
if (data['type'] === HttpEventType.UploadProgress) {
console.log('loaded ', data['loaded'], ' total -', data['total']);
}
})
Solution 3
This method may help
public progress: number = 0;
public message: string = "";
constructor(private http: HttpClient) {}
onSubmit() {
// replace with your request data
const formModel = this.userForm.value;
let formData = new FormData();
formData.append("upload", formModel.upload);
const uploadReq = new HttpRequest('POST', 'api/Upload', formData, {
reportProgress: true,
});
this.http.request(uploadReq).subscribe((event) => {
if (event.type === HttpEventType.UploadProgress) {
this.progress = Math.round(100 * event.loaded / event.total);
}
else if (event.type === HttpEventType.Response) {
this.message = event.body.toString();
}
});
}
Solution 4
After reading https://stackoverflow.com/a/54899930/1429439 I added the observe: 'events' parameter and started receiving the HttpEvents in my subscription.
Solution 5
return this.http.request('POST', api_enpoint , { body: body, headers: headers, reportProgress: true, withCredentials: true }).map(httpResponse => {
console.log(httpResponse);
});
Instead of passing the httpRequest object, you need to pass the request in this fashion (works for both http as well for https)
tommueller
10 years+ of development experience. Slowly migrated from back- to frontend. Currently in love with Angular.
Updated on July 21, 2022Comments
-
tommueller over 1 year
I am implementing a file upload service with Angular 5 and I want to give the user some feedback on the upload progress. I found several pages suggesting to use the
reportProgress
parameter that comes with AngularsHttpClient
, but I cannot get it working.I use a wrapper class for all my http-requests, which then does some logic and finally all requests end up in the same method that's being called:
public request(request: HttpRequest<any>, options?: any): Observable<any> { return this.httpClient.request(request.method, request.url, { body: request.body, headers: request.headers, responseType: request.responseType, ...options }); }
I then pass a upload (post) call to it, with
{ reportProgress: true }
asoptions
. This did not work at all, nothing on the request changed. So I suspected, that I actually need to use thereportProgress
-parameter in the HttpRequest constructor to make it work and changed my code accordingly:public request(request: HttpRequest<any>, options?: any): Observable<any> { return this.httpClient.request( new HttpRequest(request.method, request.url, request.body, { headers: request.headers, responseType: request.responseType, ...options }) ); }
This leads to the even more weird behavior, that now no matter what my options look like, I always only receive
{type: 0}
as response from the request.What am I overseeing? I use Angular 5.1.1 and I am really a bit puzzled here right now.
So to give an explicit example, right now I receive the same response for those two HttpRequests:
{ "url":"http://127.0.0.1:8888/test", "body":{ "data":"testdata" }, "reportProgress":false, "withCredentials":false, "responseType":"json", "method":"POST", "headers":{ some-headers ... } }
and this request:
{ "url":"http://127.0.0.1:8888/api/pages", "body":{ "pageUrl":"http://localhost:1234/" }, "reportProgress":true, "withCredentials":false, "responseType":"json", "method":"POST", "headers":{ some-headers ... } }
-
tommueller about 6 yearssorry, but this is just the first snippet you find when googling how to track upload progess with angular (which I already found: "I found several pages suggesting to use the reportProgress parameter"). The answer does not give any input on my actual question ...
-
Sam B about 6 years@newnoise, it's what I'm currently using and it works; even if it is the first result in Google.
-
DoubleA over 5 yearsCan you add more detail about how you solved the issue?
-
Wilt about 5 yearsIn the documentation you can find more details: "The observe value determines the return type, according to what you are interested in observing" 1) An observe value of events returns an observable of the raw
HttpEvent
stream, including progress events by default. 2) An observe value of response returns an observable ofHttpResponse<T>
, where theT
parameter depends on theresponseType
and any optionally provided type parameter. 3) An observe value of body returns an observable of<T>
with the sameT
body type. -
Sanal S about 4 years
observe: "events"
makes the file corrupt -
Shantam Mittal about 4 yearsI have been using the same. Works good for me. If you could share more details regarding you project.
-
Syed Ali almost 4 yearswhat was the misconfig in the backend? do we need any special handling in the backend?