4

We are developing Angular(4) app and we enabled service workers using the cli

Everything works great except that we have a file upload progress bar that is stuck on 0% and only after it finishes it goes to 100%.

We suspect it's because of the service worker since we do not see it on our dev env.

What is strange that from my understanding service workers shouldn't work on posts requests.

We use regular HttpClient for it.

How can this be fixed?

Edit:

Now I'm sure it is something related to service workers because when I press on "Bypass for network" in the application tab it works fine.

doron
  • 1,508
  • 3
  • 18
  • 27
  • I guys you do this progress is 0% when you start your call. And set it again when the call end. Try: `.subscribe(data =>{ this.data = data; // progress 50% this.someFunction() // progress 75% });` When finish 100%. – Swoox Oct 19 '17 at 09:08
  • That exactly what we have done. This doesn't work with AOT + Service workers enabled – doron Oct 19 '17 at 09:20
  • Then it goes to quick ;) You see 50% in 0,001 sec then 75% in 0,002 sec and 100% in 0,003 sec – Swoox Oct 19 '17 at 09:22
  • It is not that. We are uploading 70mb files which takes few minutes to upload. We only see 0 and 100. nothing in between. If i hard reresh i see it so it must be the service workers. – doron Oct 19 '17 at 10:00
  • My Idea would be make a **countdown** **outside** the **subscribe** set it one a few milisecond or what ever. Every time the time finish it check `if(this.data === undefined) { //progress } else { //unsubscribe }`. – Swoox Oct 19 '17 at 10:14
  • Please read what i wrote. The problem is not with how i calculate the progress bar. The problem is that somehow the service worker stop this event. If i disable the service worker it works as expected. – doron Oct 19 '17 at 10:48
  • @doron Even I am facing similar issue like yours, did you find a solution for this? Progress bar works well in dev env but not in prod. – GURURAJ DHARANI Mar 25 '20 at 14:49
  • @GURURAJDHARANI yes. I’m running a gulp task to modify ngsw file that is generated after the build. You can also pass a header if possible like one of the answers below – doron Mar 26 '20 at 06:50

4 Answers4

6

Angular service worker is filtering all yours fetch request and as you need this to update your file upload progress, you can not track your upload progress. This is something imporant to take in account because (maybe) in the future you need this kind of request (FETCH) to perform other actions. If you are using latest version of angular service worker, then you can add a header to your request in order to tell Angular Service Worker (ngsw): Hey don´t filter fetch calls from this request!

In order to do what I mentioned above, you just have to add a header to your Http call, the header has to be: { 'ngsw-bypass': 'true' }

This header will tell to ngsw that have to let pass all Fetch produced by your httpClient call.

For example:

HttpClient.post(apiPath, 
   formData, 
   { 
     reportProgress: true, 
     observe: 'events', 
     headers: new HttpHeaders({ 'ngsw-bypass': 'true' }) 
   }).subscribe({
      next(events) {
          if (events.type === HttpEventType.UploadProgress) {
              // Math.round((events.loaded / events.total) * 100)
          }
      }, complete() {
          // some code here
      }, error(error) {
          // some code here
      }
   })
  • I know that preferred Angular answer but what we have done is to have a gulp task running on the ngsw file and modifies if. I like this solution better because I have the control of what’s been cached and not the BE – doron Jan 24 '20 at 06:44
  • thanks! worked for me on angular 8 app with pwa – Prem G May 07 '22 at 12:36
2

I would suggest updating your service worker to ignore post requests. I had a similar issue, except I wasn't using angular.

self.addEventListener("fetch", event => {
    //This is the code that ignores post requests
    if (event.request.method === "POST") {
        return;
    }

    //The rest of your code to handle fetch events.
});
joeshmoe301
  • 1,193
  • 2
  • 11
  • 25
0

I would recommend you to have a look to this previous question . It is not exactly the same case as yours but it can serve you as an initial point! You should read about progressEventObservable!

m33n
  • 1,622
  • 15
  • 38
0

For a temporary workaround, you have to modify your ngsw-worker.js.

  1. In ngsw-worker.js file, look for onFetch function.
  2. Modify onFetch function so that it stops executing when detecting your upload endpoint.
  3. Refer to the code snippet below:
onFetch(event) {
  if (event.request.url.indexOf('upload') !== -1) {
    return;
  }
  ...
}

You can check out this article for more information.

Jun
  • 2,942
  • 5
  • 28
  • 50