Search code examples
angulartypescriptfile-uploadprogress-barproduction

reportProgress is not working in production


When I'm uploading video file, it works normally on local (develop mode). But when i'm uploading it to the server (prod), it doesn't work.
Here is the service:

uploadVideo(id: String, file, imageId) {
        let formData = new FormData();
        formData.append('video', file);
        formData.append('imageId', imageId);
        return this.http.post<any>(`.../${id}/video`, formData, {reportProgress: true, observe: 'events'})
                .pipe(map(response => {
                        return response;
                }));
    }

Here is the component ->

this.arrivalProductService.uploadVideo(this.data.id, this.selectedFile, imageId)
      .pipe(
        map((event) => {
          console.log('event', event);
          if(event.type === HttpEventType.UploadProgress){
            const percentDone = Math.round(100 * event.loaded / event.total);
            return { status: 'progress', message: percentDone };
          }
          if (event.type === HttpEventType.Response) {
            return event.body;
          }
        }),
        catchError(error => {
          return throwError(error);
        }),
        finalize(() => {
          console.log('completed');
        })
      )
      .subscribe(
        data => {
          ....
       })

If I'm logging event on map(), on local dev it return all progress: like ({status: 'progress', message: 0}, ... etc), on production it returns nothing..
I can't understand what's wrong with the code.. please help me


Solution

  • You are probably using a service worker in your production build.

    https://angular.io/guide/service-worker-devops#bypassing-the-service-worker

    Bypassing the service worker In some cases, you may want to bypass the service worker entirely and let the browser handle the request instead. An example is when you rely on a feature that is currently not supported in service workers (e.g. reporting progress on uploaded files).

    To bypass the service worker you can set ngsw-bypass as a request header, or as a query parameter. (The value of the header or query parameter is ignored and can be empty or omitted.)

    so in your case:

    uploadVideo(id: String, file, imageId) {
            let formData = new FormData();
            const headers = new HttpHeaders({ 'ngsw-bypass': ''});
    
            formData.append('video', file);
            formData.append('imageId', imageId);
            return this.http.post<any>(`.../${id}/video`, formData, {reportProgress: true, observe: 'events', headers: headers})
                    .pipe(map(response => {
                            return response;
                    }));
    }