0

I have the next Angular service to upload files to Amazon S3 using presinged URL:

    import { Injectable } from "@angular/core";
    import { HttpClient, HttpRequest, HttpHeaders, HttpEvent, HttpEventType, HttpErrorResponse, HttpParams } from "@angular/common/http";
    import { map, tap, last } from 'rxjs/operators';

    @Injectable()
    export class S3FileUploadService {
      constructor(private _http: HttpClient) {
      }

      upload(url: string, file: File | Blob, progress: (percent: number) => void, result: (msg: StateMessage) => void) {
        const req = new HttpRequest('PUT', url, file, {
          headers: new HttpHeaders().set("Content-Type", "binary/octet-stream"),
          reportProgress: true,
        });

        this._http.request(req).pipe(
          map(event => this._getProgress(event)),
          tap(value => progress(value)),
          last()
        ).subscribe(() => {
          result({ err: false, msg: "Uploaded" });
        }, (err) => {
          result({ err: true, msg: this._errorMsg(err, "Not uploaded") });
        });
      }

      private _getProgress(event: HttpEvent<any>) {
        switch (event.type) {
          case HttpEventType.Sent:
            return 0;
          case HttpEventType.UploadProgress:
            return Math.round(10000 * event.loaded / event.total) / 100;
          case HttpEventType.Response:
            return 100;
        }
      }
    }

The service works fine in the development environment. However, in production for some reason progress event is not fired (update happens when the upload is completely finished). I've also tried to add the next params to HttpRequest object according to some examples with similar problems over the internet, but looks like it's an outdated thing and it doesn't affect anything:

    const params = new HttpParams().set("observe", "events");

What can the problem be caused by? Can it originate not from Angular build but from S3 not returning the progress?

Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
Arsenii Fomin
  • 3,120
  • 3
  • 22
  • 42

1 Answers1

0

I had the same issue and traced it to service worker. If you have service worker enabled in prod (service worker may not be built when you do ng serve) then it could be handing your POST request differently

If that's the case, then you can do some hacks as suggested here Progress bar doesn't work using service workers with angular cli

kwalski
  • 580
  • 7
  • 15