šŸŽ„ Get 20% off from our JavaScript course for the holidays! šŸŽ„
How to Sync Your Client and Server After Being Offline

How to Sync Your Client and Server After Being Offline

Save offline changes to sync later with your server
Ferenc Almasi • Last updated 2021 November 11 • Read time 5 min read
Are you already supporting offline state for your website? Learn how you can sync changes between your client and server after connection is restored.
  • twitter
  • facebook
JavaScript

PWAsĀ have become more and more commonplace. People want to access your content in uncertain conditions or even when there’s no internet connection at all. To battle this, we haveĀ service workersĀ that can help you eliminate the problems of being offline. But what happens once the connection is back and users have pending changes?

Most of the time, these changes are lost. Since there’s no connection, they are not saved to a database. But can we change this? The answer is yes. This is the time when you want to sync the changes to ensure they are kept and nothing is lost.

So how do we do this? Everything starts when things go offline.


Detecting Offline State

For detecting network changes, we have some options. First, you can add event listeners forĀ onlineĀ andĀ offlineĀ changes:

Copied to clipboard!
window.addEventListener('offline', () => { ... });
window.addEventListener('online',  () => { ... });
offline.js

This is especially useful when you want to give some feedback to the user about the changes in network conditions.

Going offline shows banner
Banner is shown when the user goes offline

Apart from event listeners, we can also check the value ofĀ navigator.onLine. If this value turns out to be true, we can save changes locally only to sync them later with the server.


Queue Updates

To queue network requests, we need to store information on the user’s machine. We also need to account for page refreshes or even closing the browser altogether. This can be done with the use ofĀ localStorage. Let’s create anĀ offlineServiceĀ that can catch network requests to later reuse them for syncing:

Copied to clipboard! Playground
const offlineService = {
    
    getQueue() {
        return JSON.parse(localStorage.getItem('queue') || '[]');
    },

    deferRequest(payload) {
        const queue = this.getQueue();

        queue.push(payload);

        localStorage.setItem('queue', JSON.stringify(queue));
    },

    clearQueue() {
        localStorage.removeItem('queue');
    }
};
offlineService.js

For this, we can create an object with three different methods:

  • getQueueĀ for getting theĀ localStorageĀ itemĀ queue. Here, we can fallback to a string representation of an empty array in case we don’t have aĀ queueĀ inĀ localStorage.
  • deferRequestĀ for adding network requests to theĀ queue.
  • clearQueueĀ for removing the pending network requests.

Note that we have to useĀ JSON.parseĀ andĀ JSON.stringifyĀ to be able to save toĀ localStorage.

By exporting the object and importing it to a service that handles API requests, we can useĀ navigator.onLineĀ to check the network condition:

Copied to clipboard! Playground
// Service that receives all requests to the API
APIRequest(params) {
    if (!navigator.onLine) {
        offlineService.deferRequest(params);
    } else {
        return fetch(params.url, {
            body: params.body,
            method: params.method,
            headers: params.headers
        }).then(response => {
            return response.json();
        }).catch(error => {
            console.log(error);
        });
    }
}
httpService.js

And we either use our newly createdĀ offlineServiceĀ to defer requests or we continue sending them as usual. Every time a request is made, this will create a new object in theĀ queueĀ array with the request URL, body, method, and headers—everything that is needed to later sync pending changes with the server.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript Remove ads

Syncing With Database

The last thing to do is to finally sync the changes with the server once the connection is restored:

Copied to clipboard! Playground
window.addEventListener('online', () => {
    if (offlineService.getQueue().length) {
        const deferredRequests = offlineService.getQueue();
  
        deferredRequests.forEach(async payload => await APIRequest(payload));
        
        offlineService.clearQueue();
    }
});
sync.js

First, we can check if there’s anything in the array just to be sure. If there is, we get it, and for each request that has been queued, we call the function that handles the API requests with the payload provided. Then we can clear the queue since nothing needs to updated again.


Summary

All that’s left to do is to check if everything works as expected. I also added some CSS animation to it to show the user that something is going on in the background:

Trying out syncing with DB

When I go offline, first the notification comes up. This is due to the event listener added to theĀ offlineĀ event. Then I try to add a couple of items and set the connection back toĀ onlineĀ in the Network tab. And we get back four requests for the four changes.

This combined with a service worker and PWA configuration can really take the offline experience of your application to the next level. Users can confidently keep on working even when the connection is lost. And since all information is stored insideĀ localStorage, this information will survive even if you close the tab.

Thank you for reading through. Are there any ways you try to deal with being offline? If so, let us know in the comments section below.

Did you find this page helpful?
šŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access exclusive interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Remove ads to learn without distractions
Become a Pro

Recommended