I used @angular/service-worker
module to generate a service-worker to cache all static assets for my Angular 7 app and it works well (in network tab on chrome dev tools, these files are tagged as from ServiceWorker
).
What I am trying to do is adding cache support (and background sync) to data got from an external API. I know that @angular/service-worker
module supports dataGroups
type of assets but I would like to do something more complicated : serving cache data first then fetch data through network, update the cache and finally return a second, fresher response. This idea is described in the offline cookbook : https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-then-network
So I need to add a custom SW coexisting with the one generated by Angular. Problem is my fetch
event listener is never fired.
I register my service worker :
ServiceWorkerModule.register('../sw.js', { enabled: environment.production }),
in app.module.ts.
sw.js file imports ngsw-worker.js (which is generated by Angular) :
importScripts('./ngsw-worker.js');
importScripts('./sw-custom.js');
Then, sw-custom.js
is adding two events listener on install
and fetch
:
self.addEventListener('install', function(event) {
try {
console.log('typeof System in install', typeof System);
} catch(e){}
console.log('caching');
event.waitUntil(
caches.open(CACHE_VERSION).then(function(cache) {
console.log('caching - getting');
return;
}).catch(function(error){ console.log('error', error) })
);
});
self.addEventListener('fetch', event => {
console.log('Hello service worker');
if (event.request.method !== 'GET') return;
const request = event.request.clone();
// Do stuff
event.respondWith(fetch(request));
});
The listener on install
event is executed, but not the fetch
one and I can't understand why.
The problem is that you're importing Angular ngsw-worker.js
first, it contains it's own listeners that can prevent your listener from being executed.
Try changing the import order like this:
importScripts('./sw-custom.js');
importScripts('./ngsw-worker.js');
Also, you may need to prevent angular generated listeners to run by stopping the event propagation avoiding things like duplicate fetches:
self.addEventListener('fetch', event => {
console.log('Hello service worker');
if (event.request.method !== 'GET') return;
const request = event.request.clone();
// Do stuff
event.respondWith(fetch(request));
// stop propagation to Angular Service Worker if we need
event.stopImmediatePropagation();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With