donniebrandt's avatar

Vue2: Properly Clone A Vuex Object For Manipulation

I am retrieving a viewSettings object via viewSettingsGetter in Vuex and need to clone it in order to manipulate the copy _(since manipulating the object directly is forbidden)_. However, every attempt so far throws this error when I make a change:

[Vue warn]: Error in watcher "state"

To be clear, I can read the object fine, I just need to know how to duplicate the object so that I can manipulate the local copy?

const getters = {
  viewSettingsGetter: state => state.viewSettings
};

I have tried these methods to make a copy of the object:

Failed Attempt A

computed: {
  ...mapGetters(['viewSettingsGetter'])
},

data () {
  return {
    viewSettings: this.viewSettingsGetter
  };
},

Failed Attempt B

computed: {
  ...mapGetters(['viewSettingsGetter'])
},

data () {
  return {
    viewSettings: {}
  };
},

mounted () {
  this.$set(this.viewSettings, this.viewSettingsGetter); // Vue.js method
}

Failed Attempt C

computed: {
  ...mapGetters(['viewSettingsGetter'])
},

data () {
  return {
    viewSettings: {}
  };
},

mounted () {
  this.viewSettings = _.clone(this.viewSettingsGetter); // lodash.js method
}
0 likes
6 replies
WebKenth's avatar

What exactly are you trying to do?

Do you want to add properties to the object? Strip properties?

A quick guess would to be try your manipulation in beforeCreate() rather than the mounted as object observers havn't been attached yet

Vue Lifecycle Hooks

1 like
donniebrandt's avatar

I will mainly be rearranging and adding/removing values to nested arrays. beforeCreate() may be premature, so I will explore the options.

Update: It turns out that created() is perfect!

Update 2: I later discovered that this, in fact, did not work the way I needed, so see my other solution.

kingsloi's avatar

@donniebrandt, hey buddy, are you able to post your solution? I'm currently going through this, no matter what I try I can't wrap my head around it. I get the same message no matter what part of the lifecycle I add to

1 like
donniebrandt's avatar
donniebrandt
OP
Best Answer
Level 4

Hey @kingsloi, I ended up settling on this getter which recreates the data object while leaving the watchers and restrictions behind, although it is still reactive when the value changes in Vuex.

viewSettingsGetter: state => { return JSON.parse(JSON.stringify(state.viewSettings)); }

pdcmoreira's avatar

The accepted solution doesn't work if the object is an instance of a class.

Serzh's avatar

Well I have two options:

  1. let clone = this._.cloneDeep(this.original) with lodash

  2. let clone = JSON.parse(JSON.stringify(this.original))

Please or to participate in this conversation.