Reputation: 4587
Suppose I'm using an external API which works with Machine
objects. You can create a Machine
with createMachine
, which will give you a complex object with several nested properties, and a set of functions to alter state on that object. The API provides for example: loadMemory
, sleep
, connectDevice
. (Imagine anything similar, this is just an example).
I want to mantain a global Vuex Machine
object, so I've an action to dispatch that initial creation and store the returned object just like:
actions: {
createChannel({ commit, state }, params) {
m.createMachine(params).then(
function (newMachine) {
commit('setMachine', newMachine);
}
).catch(err => { console.error("Error"); } )
}
}
The mutation is pretty straightforward in this case:
setMachine(state, machine) {
state.machine = machine;
}
Now that API set for the "Machine" objects, as we know has a bunch of state-modifying calls -we don't know what specific fields they change-.
As they modify state, and I want to use them to affect the global Machine
object in the Vuex store, I would like to wrap them in actions.
An action could call
this.state.machine.loadMemory(mem.addr)
But if this call itself modified the machine
object, how do I commit the new state? Should I clone the old object, apply the state-changing method and replace the object ?
I know cloning is not an easy task.
Thanks.
Upvotes: 2
Views: 283
Reputation: 22393
One way is using lodash cloneDeep, it will copy app properties and methods of object
import _ from lodash
this.state.machine.loadMemory(mem.addr)
const copyMachine = _.cloneDeep(this.state.machine)
this.$store.commit('setMachine', copyMachine)
Upvotes: 1
Reputation: 919
You can re-mount your complex object. According to the example, the mutation could be:
loadMemory(state, newAddr) {
const { machine } = state;
state.machine = {
...machine, // set all machine's properties
addr: newAddr,
};
}
It works in any level of nested objects you want. Another example:
loadMemory(state, newValue) {
const { machine } = state;
const { machineObjProp } = machine;
state.machine = {
...machine, // set all machine's properties
machineObjProp: {
...machineObjProp, // set all machineObjProp's properties
value: newValue,
},
};
}
Upvotes: 2