Synchronize Local Database from Remote Server on IONIC

Asked

Viewed 3,161 times

3

Personal how to update a database in a mobile application every time the remote database is updated.

For example I have an application in Ionic, and to get faster I use the database of contacts query locally however this data is updated remotely, so I need to update the local database of the mobile application.

I have two forms of Local database, one is loading a JSON file:

$http.get('js/dados.json').then(function(response) {
 angular.forEach(response.data, function(items) {
  $scope.total = items.length;
  for (i=0; i < $scope.limite; i++) {
    $scope.chats.push(items[i]);
  }
 });
}

In another example I load the data from an Sqlite:

$scope.select = function(lastname) {
    var query = "SELECT firstname, lastname FROM people WHERE lastname = ?";
    $cordovaSQLite.execute(db, query, [lastname]).then(function(res) {
        if(res.rows.length > 0) {
            console.log("SELECTED -> " + res.rows.item(0).firstname + " " + res.rows.item(0).lastname);
        } else {
            console.log("No results found");
        }
    }, function (err) {
        console.error(err);
    });
}

https://blog.nraboy.com/2014/11/use-sqlite-instead-local-storage-ionic-framework/

Would anyone have any solution to this.

  • I have the same doubt, I will go while researching I will follow answers here!

1 answer

1

Old question, but I hope that this answer will serve the other Googlers.

I’ll give you an example of how to do it. (untested code!)

Create the Factory below: it stores your contacts in memory, in the variable atuais which is only accessible through the function getContatos()

.factory('Contato',  function () {

   var atuais = { last: 0, contatos: {} };

   var ContatoFactory = {

        setContatos: function(novos) {   
            var processed = 0;
            if (isPresent(novos)) {
                if (atuais.last<novos.last) {
                    if (isPresent(novos.contatos)) {
                        atuais.last = novos.last;

                        for (var key in novos.contatos) {
                            if (!atuais.contatos[key]) atuais.contatos[key] = {};
                            angular.copy(novos.contatos[key],  atuais.contatos[key]);
                            processed++;
                        }
                    } else {
                        console.log('setContatos: falhou: novos.contatos = ' + novos.contatos);
                    }
                } else {
                    console.log('setContatos: falhou: atuais.last [' + atuais.last + '] >= novos.last [' + novos.last + ']');
                }
            } else {
                console.log('setContatos: nenhum contato novo para processar');
            }
            console.log('setContatos: ', processed, ' contatos processados');
        },
        getContatos: function() {
            console.log('getContatos: ' + angular.toJson(atuais) );
            return angular.copy(atuais);
        },
        clearContatos: function() {
            angular.copy({ last:0, contatos: {} }, atuais);
            console.log('clearContatos: ' + angular.toJson(atuais) );
        },
        persistirContatos: function() {
            //seu código aqui para salvar no SQLite ou LocalStorage
            //exemplo:
            localStorage.setItem('meusContatos', angular.toJson(atuais) );
        }
   };
   return ContatoFactory;
})

Somewhere in your code, you will recover backend contacts via AJAX (don’t forget to inject your Factory to be able to use it):

$http({
  method: 'GET',
  url: 'http://meuServidor.com/contatos?last=' + lastPosixUpdate
}).then(function successCallback(response) {
      Contato.setContato(response);  // response => { last: <POSIX_DATE>, contatos: { key1: {nome: 'abc', fone: '123' },  key2: {nome: 'xyz', fone: '456'}, ... }  }    
  }, function errorCallback(response) {
    console.log('Ajax falhou');
  });

Then you can recover your contacts in any controller of your App:

$scope.contatos = Contato.getContatos();

Similarly you can persist your data when you find it convenient:

Contato.persistirContatos();

See that the backend sends a JSON like this:

{ last: <POSIX_DATE>, contatos: { key1: {nome: 'abc', fone: '123' },  key2: {nome: 'xyz', fone: '456'}, ... }  } 

whereas last must be a number representing the last executed change in the contact table. Thus, the answer will only be processed if there are new or changed contacts.

Similarly, the $http.get sends a last=238274 querystring to signal to the backend from when it wants the contact updates.

You can implement that last (which is good when the contact list is huge) or simply recover all contacts always.

auxiliary function:

//retorna true se o objeto existe e é não vazio
function isPresent(obj) {
    return obj && (Object.keys(obj).length!==0);
}
  • Perfect, very well executed explanation and very important for all who need explanations on the subject, worth Fernando.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.