1

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.

sjaustirni
  • 3,056
  • 7
  • 32
  • 50
  • 1
    You can't directly replace the state like you are trying to do in `updateArray`, where `from` is effectively the `state`. If you want to replace the complete state you need to use the `replaceState` method of the store instance. Moreover, you're not really using Vuex as intended. Mutations are intended to receive the state object and mutations should be *commited* via the store. – Bert Jan 04 '18 at 15:40
  • @Bert: I don't want to replace the whole state though. I have many an array in the state (just stripped it down to simplify it for you) and I need to update only the very specific array. Is there a way to do it? – sjaustirni Jan 04 '18 at 15:45
  • @Bert: I am using it like you have described in the components, however, I need to load the data from the LokiJS database first. Is there an idiomatic way to do it? – sjaustirni Jan 04 '18 at 15:48
  • 1
    As I show below you can call methods on the store without using `this.$store`, you just need a reference to the store object. So *outside* a component, you would do it it same way you would *inside* the component, it's just a matter of how you get to the store. – Bert Jan 04 '18 at 15:53
  • @Bert: I see. It is unfortunate though, because even though the JSFiddle example does have access to the store object, in my application it is a module which I `export default { ... }`. I have no idea how I would get the store object then. – sjaustirni Jan 04 '18 at 15:56
  • 1
    Typically you export the store object and just import it where you need it. – Bert Jan 04 '18 at 15:58
  • Thanks @Bert, it solved my issue :) – sjaustirni Jan 04 '18 at 16:01

1 Answers1

1

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.

Bert
  • 80,741
  • 17
  • 199
  • 164