- Show 'SyncManager' and 'Notification' objects in window
- Request approval for notifications in the browser
- If serviceWorker registration and installation is successful and the serviceWorker is ready, then add an event listener to the submit button to add an article to the sync queue
main.js
if ('serviceWorker' in navigator && 'SyncManager' in window && 'Notification' in window) {
window.addEventListener('load', () => {
fetchLatestHeadlines();
navigator.serviceWorker.register('./service-worker.js')
.then(registration => navigator.serviceWorker.ready)
.then(registration => {
Notification.requestPermission();
$('#submit-article').on('click', function(event) {
let headline = $('#headline-input').val();
let byline = $('#byline-input').val();
navigator.serviceWorker.controller.postMessage({
type: 'add-article',
article: { headline, byline, id: Math.random() }
});
});
}).catch(err => {
// registration failed :(
console.log(`ServiceWorker registration failed: ${err}`);
});
});
}
- Add service worker event listener for a message of type
add-article
- Add synceQueue to store data about the article that was previously retrieved from the form
- Register an
addArticle
sync event
service-worker.js
self.addEventListener('message', (event) => {
if (event.data.type === 'add-article') {
syncQueue.push(event.data.article);
}
self.registration.sync.register('addArticle')
});
let syncQueue = [];
- Add handler for any sync event, and then look for a sync event with a tag of
addArticle
- Wait untill will try to run addArticle immediately, but if it fails, then it will try again at some time, then next time we know it will try is a network event
- Once we get a success, send a message to our client-side code that the service worker client has new information
- Give the user a notification that the article has been sent
service-worker.js
self.addEventListener('sync', function (event) {
if (event.tag === 'addArticle') {
event.waitUntil(addArticle()
.then(response => response.json())
.then(articles => {
self.clients.matchAll().then(clients => {
clients[0].postMessage({ articles: articles });
});
self.registration.showNotification("Added new article");
})
.catch(error => {
console.log('error: ', error);
})
);
}
});
- Add the addArticle function (we're just returning the promise and resolving it in the previous event listner)
service-worker.js
const addArticle = () => {
let newestArticle = syncQueue.shift();
return fetch('/api/v1/articles', {
method: 'POST',
body: JSON.stringify(newestArticle),
headers: { 'Content-Type': 'application/json' }
});
}
- Add event listener for service worker message
main.js
navigator.serviceWorker.addEventListener('message', function(event) {
if (event.data.articles) {
appendArticles(event.data.articles);
}
});