'Updating DOM using data I receive fromm PUSH event in Service Worker

I am a beginner in Service Worker domain, Right now I am able show notification but my requirement is to update DOM using the data I receive from push event. I tried using postMessage api. But I am not understanding how to use. I tried using the answer to [Chrome ServiceWorker postMessage but I am not able use it. Can anyone help me with example, so I can understand and complete this!? In Main js..I am using initializeUI() I am calling sendMessage and subscription for user::

if ('serviceWorker' in navigator && 'PushManager' in window) {
    navigator.serviceWorker.register('../js/sw.js', {scope: 'xyz'})
            .then(function (swReg) {
                console.log('Service Worker is registered', swReg);
                swRegistration = swReg;
        initializeUI();
            })
            .catch(function (error) {
                console.error('Service Worker Error', error);
            });
} else {
    console.warn('Push messaging is not supported');
    pushButton.textContent = 'Push Not Supported';
} 

function sendMessage(message) {
    return new Promise(function (resolve, reject) {
        var messageChannel = new MessageChannel();
        messageChannel.port1.onmessage = function (event) {
            if (event.data.error) {
                reject(event.data.error);
                console.log('rejected message');
            } else {enter code here
                resolve(event.data);
                console.log('received message :: ' + event.data);
            }
        };
        navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
    });
}

and in sw.js

self.addEventListener('message', function(event) {
    console.log('inside message listener');
  event.ports[0].postMessage({'test': 'This is my response.'});
});
self.addEventListener('push', function (event) {
    console.log('[Service Worker] Push Received.');
    console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
    const title = 'New Project';
    const options = {
        body: `"${event.data.text()}"`,
        icon: 'images/icon.png',
        badge: 'images/badge.png'
    };
    console.log("data :: " + event.data.text());
event.waitUntil(self.registration.showNotification(title, options));
});

Thank you



Solution 1:[1]

There is no need to setup a messageChannel if you have a one way requirements to push messages from service worker to the DOM thread. which is typically the case with push notification.

In brief, inside the 'push' handler of your service worker you can grab the client window that is controlled by it and call postMessage on client window .Then on client window side you can listen to service worker 'message' event

Here is in the code:

On the service worker side :

self.addEventListener('push', function(event) {
  console.log(`Push Received w. this data: ${event.data.text()}`);
  //this custom async function sends it to the window 
  self.sendMessageToClient(event.data.text());
});

self.sendMessageToClient = async (message) => {
 // Send to any window client controlled by this service worker
  const clientList = await clients.matchAll({ type: "window" });
  for (let client of clientList) {
    client.postMessage(message);
    console.log(`${message} sent to window client`,client)
  }
}

On the DOM thread (i.e. client window) side :

navigator.serviceWorker.addEventListener('message', event => {
  console.log("Message from SW : ", event.data);
  const div = document.createElement("DIV");
  div.innerText = JSON.stringify(event.data);
  //adds notification message as new div to element w. swNotifs id
  document.getElementById("swNotifs").appendChild(div);
});

.

you can still do other things in 'push' handler for example sending message to notification center of your OS

event.waitUntil(self.registration.showNotification(title, options));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pref