Skip to content

Instantly share code, notes, and snippets.

@TrevorPage
Last active March 26, 2017 09:19
Show Gist options
  • Save TrevorPage/ed1ddf5c6ca39b15d2763f981a9d0232 to your computer and use it in GitHub Desktop.
Save TrevorPage/ed1ddf5c6ca39b15d2763f981a9d0232 to your computer and use it in GitHub Desktop.
Forced bulk update / rebase endpoint for StrongLoop LoopBack Synchronization, avoiding conflict resolution
// ------------------------------------------------------------------------
Dashcomponent.bulkUpdateForced = function(updates, cb) {
console.log("bulkUpdateForced");
console.log(updates, null, 2);
var that = this;
var Model = this;
var Change = Model.getChangeModel();
async.each(updates, function(update, callback) {
console.log("looking for model ID " + update.change.modelId);
Model.findById(update.change.modelId, function(err, instance) {
if(err) {
callback(err);
return;
}
var rev = Change.revisionForInst(instance);
update.change.prev = rev;
callback();
});
}, function(err) {
if(err)
console.log(err);
else {
console.log(updates, null, 2);
that.bulkUpdate(updates, cb);
}
});
};
Dashcomponent.remoteMethod('bulkUpdateForced', {
description:'As bulk-update, but forced, by setting the applied updates\' prev revision to the current rev.',
accepts: [
{arg: 'updates', type: 'array'},
],
http: {verb: 'post', path: '/bulk-update-forced'},
});
// ------------------------------------------------------------------------
@TrevorPage
Copy link
Author

TrevorPage commented Mar 26, 2017

I am using LoopBack to create a backend which Android clients will use. I am making use of LoopBack's Synchronization feature (https://loopback.io/doc/en/lb3/Synchronization.html), but in a sort of limited way. LoopBack's synchronization is intended to work such that the client is running LoopBack as well. For me however, my Android client Application isn't running LoopBack. Rather, I'm just using the LoopBack server's sync endpoints on my models "raw". So in other words, for my Android app to get latest changes from server, it'll GET the /my-model/changes and then /my-model/get-updates to get an array of LoopBack change objects which it uses to update the local SQL database. Similarly it will POST to /my-model/bulk-update to push changes to the server.

Now in my current simplistic use case, only the owner of objects shall be able to modify those objects, and I don't want nor need to bother hassling the user with the concept of conflict resolution.

The problem I had was that when using bulk-update the submitted change array had to specify the prev revision hash for each object, and a conflict arises if that prev hash the client provides doesn't match the current rev of the object at the server database. However I didn't want my Android client to have to track or generate correct prev hashes. Rather I just wanted to force the server to accept these updates.

The point of this bulk-update-forced endpoint, which 'wraps' bulkUpdate is that it works as bulk-update except the submitted change array does not need to specify the prev revision hash. This endpoint cheats by going through the updates array and inserting each affected object's current rev as the prev property. Then bulkUpdate() is called, which is now happy to create/update the objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment