vue.jsvuexlokijs

Updating Vuex state changes LokiJS data, too. Why? Vuex / LokiJS


My app workflow is getting some data from API backend, and write to client storage with help of LokiJS. I have thousands of data in client collections. For my app's state management I use Vuex.

And here is the problem. When I commit changes to my Vuex state, it changes my data on LokiJS storage, too. How can I avoid this?

I have Vuex action to get users from LS (lokijs storage)

getStudentByClass({ state, commit }) {
  const stds = students.collection.find({ class_id: state.classId });
  commit('setStudents', stds);
}

selectStudent(state, index) {
  const student = state.students[index];
  Vue.set(student, 'selected', !student.selected);
}

and Vuex mutation

setStudents(state, students) {
   state.students = students
}

as show above; with selectStudent function I change my students selected attribute on Vuex store, but that changes on LS too.

original LS data looks like this

$loki: 63
class_id: 5
color: "green"
id: 248
meta: Object
name: "John Doe"
point: 100
teacher: 0
updated_at: "2017-01-24 10:00:34"
username: "johdoe"

LS data changed

$loki: (...)
class_id: (...)
color: (...)
id: (...)
meta: (...)
name: (...)
point: (...)
selected: true <--------------- here
teacher: (...)
updated_at: (...)
username: (...)
__ob__: Observer
get $loki: function reactiveGetter()
set $loki: function reactiveSetter(newVal)
// skipped

Solution

  • Well, objects are passed by reference in JS, so changing them in vuex also change them in loki. Nothing unusual about that.

    If you don't want that, you should use a package like clone-deep to clone the result from loki before passing it to vuex (lodash has such a function as well in case you use it).