Skip to main content

State Syncing

State Syncing

You may have encountered state management libraries like Redux or Vuex. These are fantastic libraries, but their usefulness is lessened with Spraypaint. As a full-fledged model layer, Spraypaint manages state for you, automatically.

If you opt-in to this feature:

ApplicationRecord.sync = true

Instances will sync up whenever the server tells us about updated state. Consider the scenario where an instance is initially loaded, then separately polled in the background:

let person = (await Person.find(1)).data

let poll = () => {
await Person.find(1)
setTimeout(poll, 1000)
}
poll()
Person.find(1).then(function(response) {
var person = response.data;
});

var poll = function() {
Person.find(1);
setTimeout(poll, 1000);
}
poll()

Our poll() function never assigns or updates person. But if the server returns an updated name attribute, person.name will be automatically updated. This is true even if person.name is bound in 17 different nested components.

Instances can still update their attributes independently - we only sync when the server returns updated data:

let instanceA = (await Person.find(1)).data
let instanceB = (await Person.find(1)).data

instanceA.name // "Jane"
instanceB.name // "Jane"

instanceB.name = "Silvia"
instanceA.name // "Jane"
instanceB.name // "Silvia"

await instanceB.save()
instanceA.name // "Silvia"
instanceB.name // "Silvia"
var instanceA, instanceB;
Person.find(1).then(function(response) {
instanceA = response.data;
});
Person.find(1).then(function(response) {
instanceB = response.data;
});

instanceA.name // "Jane"
instanceB.name // "Jane"

instanceB.name = "Silvia"
instanceA.name // "Jane"
instanceB.name // "Silvia"

instanceB.save().then(function() {
instanceA.name // "Silvia"
instanceB.name // "Silvia"
});

Gotchas

Under the hood, instances are listening for updates from a central data store. This means that you'll want to remove listeners whenever you no longer need the instance - otherwise it will never be garbage collected properly. To remove a listener:

instance.unlisten()

In practice, when developing in a SPA, you'll want to #unlisten() whenever a view is destroyed and model instances no longer need to be referenced. If you are using VueJS, this is done automatically by adding spraypaint-vue to your application.