Question:
Personal how-to 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 contact lookup locally however this data is updated remotely, this way 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 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/
Anyone would have any solution for this.
Answer:
Old question, but I hope this answer will be useful for 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 atuais
variable which is only accessible through the getContatos()
function
.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'll retrieve the backend contacts via AJAX (don't forget to inject your Factory in order 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 retrieve your contacts on any controller in your App:
$scope.contatos = Contato.getContatos();
In the same way, you can persist your data when you see fit:
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'}, ... } }
where last
must be a number representing the last change performed in the contact table. Thus, the response will only be processed if there are new or changed contacts.
Likewise, $http.get
sends a querystring last=238274 to signal the backend as of when it wants contact updates.
You can implement such a last
(which is good when the contact list is huge) or simply retrieve 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);
}