HttpRequest and reportProgress not working or messing up my requests

14,287

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)

Share:
14,287
tommueller
Author by

tommueller

10 years+ of development experience. Slowly migrated from back- to frontend. Currently in love with Angular.

Updated on July 21, 2022

Comments

  • tommueller
    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 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 ... }
    }
    
  • tommueller
    tommueller about 6 years
    sorry, 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
    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
    DoubleA over 5 years
    Can you add more detail about how you solved the issue?
  • Wilt
    Wilt about 5 years
    In 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 of HttpResponse<T>, where the T parameter depends on the responseType and any optionally provided type parameter. 3) An observe value of body returns an observable of <T> with the same T body type.
  • Sanal S
    Sanal S about 4 years
    observe: "events" makes the file corrupt
  • Shantam Mittal
    Shantam Mittal about 4 years
    I have been using the same. Works good for me. If you could share more details regarding you project.
  • Syed Ali
    Syed Ali almost 4 years
    what was the misconfig in the backend? do we need any special handling in the backend?