Checking the datastore sync status in JavaScript

Posted by Steve Marx on October 07, 2013

When your app makes a change to a datastore, that change is queued up locally and sent to Dropbox asynchronously. This means that there's a period of time between when a change is made and when that change has been uploaded to Dropbox. Because the JavaScript SDK currently provides no local persistence, pending changes will be lost if the user closes the browser tab or navigates away from the page. To prevent users from inadvertently losing changes when they navigate away from your app, you can check the "sync status" exposed by the Datastore API and take appropriate action.

Preventing navigation when uploads are pending

The JavaScript SDK provides a function called getSyncStatus(), which returns an object with an uploading field. If uploading is true, there are pending changes that haven't yet been sent to Dropbox's servers. The following code performs this check in beforeunload to warn the user that their pending updates will be lost if they navigate away from the page:

client.getDatastoreManager().openDefaultDatastore(function (error, datastore) {
    ...
    $(window).bind('beforeunload', function () {
        if (datastore.getSyncStatus().uploading) {
            return "You have pending changes that haven't been synchronized to the server.";
        }
    });
    ...
});

This code checks the sync status only when the user navigates away from the page. It's also possible to monitor changes to the sync status as they happen, which can be used to display that status to the user.

Displaying sync status

The Datastore API provides an event that's triggered every time the sync status changes. By listening to the syncStatusChanged event, your code can perform some action when uploading starts or finishes. In the following example, an HTML element is updated to either say "Pending..." or "Synchronized," based on the current sync status:

client.getDatastoreManager().openDefaultDatastore(function (error, datastore) {
    ...
    $('#status').text('Synchronized');
    datastore.syncStatusChanged.addListener(function () {
        if (datastore.getSyncStatus().uploading) {
            $('#status').text('Pending...');
        } else {
            $('#status').text('Synchronized');
        }
    });
    ...
});

When connected to the internet, changes will generally be synchronized very fast, making a status indicator more annoying than useful. An alternative to showing the status might be to show the "last save" time. Here's a code example that does that:

var previouslyUploading = false;
datastore.syncStatusChanged.addListener(function () {
    var uploading = datastore.getSyncStatus().uploading;
    if (previouslyUploading && !uploading) {
        $('#status').text('Last sync: ' + new Date());
    }
    previouslyUploading = uploading;
});

Note that the time is only updated when the uploading flag changes from true to false, meaning an upload has just completed.