Reputation: 2496
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 Angulars HttpClient
, 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 }
as options
. This did not work at all, nothing on the request changed. So I suspected, that I actually need to use the reportProgress
-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 ... }
}
Upvotes: 6
Views: 18439
Reputation: 500
if You Are using service worker you have to send ngsw-bypass
header.
example:-
file: File;
uploadProgress: number;
constructor(private http: HttpClient) { }
uploadData(): void {
const formData = new FormData();
formData.append('file', this.file);
const headers = new HttpHeaders({ 'ngsw-bypass': '' });
this.http.post(`upload url`, formData, {
reportProgress: true,
observe: 'events',
headers
}).subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
this.uploadProgress = Math.round(100 * event.loaded / event.total);
}
else if (event.type === HttpEventType.Response) {
console.log(event.body);
}
});
}
Upvotes: 2
Reputation: 3043
Upload the formdata along with header details
This snipet will help ou to upload formdata and while subscribe you can implement the progress bar as well
uploadMyImage(formData: any) {
const httpOptions = new HttpHeaders({
'Content-Type': 'multipart/form-data', 'boundary': 'something'
});
return this.http.post('http://localhost:4000/api/upload', formData, { reportProgress: true, observe: 'events', headers: httpOptions });
}
Upvotes: 0
Reputation: 383
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']);
}
})
Upvotes: 11
Reputation: 1561
After reading https://stackoverflow.com/a/54899930/1429439 I added the observe: 'events' parameter and started receiving the HttpEvents in my subscription.
Upvotes: 3
Reputation: 391
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)
Upvotes: 1
Reputation: 2496
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.
Upvotes: 4
Reputation: 115
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();
}
});
}
Upvotes: 6