Search code examples
javascriptvue.jsvuejs2vuexlokijs

Vuex state is not mutated by a general function whilst a dedicated function does mutate it


I have a LokiJS-provided storage which I use to update the Vuex state using mutations in the autoloadCallback.

LokIJS storage:

var db = new loki('mydatabase', {
  autoupdate: true,
  autoload: true,
  autoloadCallback: setupHandler
})

Vuex state and mutations:

const state = {
  ads: []
}

const mutations = {
  updateArray(from, to) {
      from = to
  },
  updateAds() {
      state.ads = db.getCollection('ads').data
  }
}

And the callback itself:

function setupHandler() {
  setupCollection('ads') // Just sets up the collection if it doesn't exist
  db.getCollection('ads').insert({dummy: "Dummmy!"})

  mutations.updateArray(state.ads, db.getCollection('ads').data)
  mutations.updateAds()    
}

The issue here is that calling the updateArray(state.ads, content) does not change the state.ads to content, but the updateAds() function which does essentially the same thing, just does not accept arguments and have them hardcoded, does change the state.ads accordingly.

What is the underlying problem with my approach to write a general function to updateArray? Is there a way to do it?


Here is an JSFiddle MCVE example of this behaviour.


Solution

  • Without knowing the specifics of loki I think you need to make the following changes.

    Your mutation should look like this:

    const mutations = {
      updateArray(state, to) {
          state.ads = to
        }
    }
    

    And your setupHandler function should look like this:

    function setupHandler() {
      setupCollection('ads')
      db.getCollection('ads').insert({dummy: "Dummmy!"})
    
      store.commit('updateArray', db.getCollection('ads').data)
    }
    

    Mutations are functions that accept the state as the first parameter, and an object argument containing parameters as the second. Mutations should be committed using the store's commit method.

    Here is your fiddle updated.