lross12
lross12

Reputation: 77

Service Worker not stopping initial requests and only appears to be used once

I asked a question last week about this and got a very helpful answer but I am still struggling to get this working as it is supposed to, although at this point I'm not entirely sure what I've been asked to do is possible.

So this service worker is supposed to activate when ?testMode=true is added to the URL and this seems to be happening okay. The service worker is then supposed to intercept specific requests before they happen and then redirect it to mock data instead. What I have got at the moment will store the mock data and call it when specific requests are made but it doesn't actually stop the initial request from happening as it still appears within the network tab.

So for example if the request contains /units/all?availability=Active&roomTypeHandle=kitchens, the service worker is meant to intercept this and instead of that request going through, mock-data/unitData.json is supposed to be used instead.

This is what I have so far:

TestMode.ts

class TestMode {
    constructor() {
        if (!this.isEnabled()) {
            return;
        }

        if (!('serviceWorker' in navigator)) {
            console.log('Browser does not support service workers');
            return;
        }

        this.init();
    }

    private init(): void {
        navigator.serviceWorker
            .register('planner-worker/js/worker.min.js')
            .then(this.handleRegistration)
            .catch((error) => { throw new Error('Service Worker registration failed: ' + error.message); });

        navigator.serviceWorker.addEventListener('message', event => {
            // event is a MessageEvent object
            console.log(`The service worker sent me a message: ${event.data}`);
        });

        navigator.serviceWorker.ready.then( registration => {
            if (!registration.active) {
                console.log('failed to communicate')

                return;
            }

            registration.active.postMessage("Hi service worker");
        });
    }

    private handleRegistration(registration: ServiceWorkerRegistration): void {
        registration.update();

        console.log('Registration successful, scope is:', registration.scope);
    }

    private isEnabled(): boolean {
        return locationService.hasParam('testMode');
    }
}

export default new TestMode(); 

serviceWorker.js

const CACHE_NAME = 'mockData-cache';

const MOCK_DATA = {
    '/units/all?availability=Active&roomTypeHandle=kitchens': 'mock-data/unitData.json',
    '/frontal-ranges/kitchens?' : 'mock-data/kitchensData.json',
    '/carcase-ranges/?availability=Active&roomTypeHandle=kitchens' : 'mock-data/carcaseRangesData.json',
    '/products/830368/related?roomTypeHandle=kitchens&productStateHandle=Active&limit=1000&campaignPhaseId=183&retailStore=Finishing%20Touches%20%28Extra%29'
    : 'mock-data/relatedItems.json'
};


self.addEventListener('install', event => {
    console.log('Attempting to install service worker and cache static assets');
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then(cache => {
                return cache.addAll(Object.values(MOCK_DATA));
            })
    );
});


self.addEventListener('activate', function(event) {
    return self.clients.claim();
});

self.addEventListener('fetch', (event) => {
    const url = new URL(event.request.url);
    const pathAndQuery = url.pathname + url.search;

    if (pathAndQuery in MOCK_DATA) {
        const cacheKey = MOCK_DATA[pathAndQuery];
        event.respondWith(
            caches.match(cacheKey, {
                cacheName: CACHE_NAME,
            })
        );
    }
});

Another thing that happens which I'm not sure how to get around is that the fetch event only happens once. By that I mean that when a change is made to serviceWorker.js, the mock data is stored in the cache and the files appear in the network tab of dev tools, but if I refresh the page, or close it and reopen in another tab, the mock data is no longer in the network tab and it's as if the service worker is not being used at all. How can I update this so that it's always used? I can see in the console log that the service worker is registered, but it just don't seem to get used.

Apologies if I shouldn't be asking 2 questions in 1 post, just really not sure how to solve my issue. Thanks in advance for any guidance.

Upvotes: 1

Views: 588

Answers (1)

lross12
lross12

Reputation: 77

Turns out my issue was a scope one. Once moving where the service worker was stored it started working as intended. Realised this was the case as I figured out the fetch event wasn't actually firing.

Upvotes: 1

Related Questions