Nuxtjs Vuex not saving changes

Viewed 397

I have data between sessions that is saved in window.localStorage. When a new session starts a plugin will grab the data and add it to the store.

// ./store/data.js

export const state = () => ({
  data: []
})

export const mutations = {
  addItemToData (state, item) {
    state.data = state.data.push(item)
  },
  setData (state, data) {
    state.data = data
  },
}

// ./store/index.js

import localStorage from '../plugins/localStorage'

export const plugins = [localStorage]

// plugins/localStorage.js

const localStorage = store => {

  store.subscribe((mutation, state) => {

    if (mutation.type === 'data/addItemToData') {
      console.log('saving added item to storage')
      window.localStorage.setItem('data', JSON.stringify(state.data.data))
    }

  })

  // called when the store is initialized
  if (typeof window !== 'undefined') {
    if (window.localStorage.data) {
      store.commit('data/setData', JSON.parse(window.localStorage.getItem('data')))
    }
  }
}

export default localStorage

I've thrown all sorts of console statements in, and they all seem to output what they should. The data is in the localStorage, the mutations are firing, but after all that the data isn't in the store.

Any help would be great, thanks!

3 Answers

several things that do not make sense and that you can resolve

#1

addItemToData (state, item) {
  state.data = state.data.push(item)
}

Array.push() does not return anything, so it should be written as

addItemToData (state, item) {
  state.data.push(item)
}

#2

in your localStorage.js file, when you initialize the data storage, you are assuming that a data variable exists:

if (window.localStorage.data) { ...

but that will never exist from the code you show, as you are adding the data to another variable

window.localStorage.setItem('cart', ...

either change cart into data or data into cart

#3

If still does not work, I would suspect that your plugin is running before the store is actually initialized, for that, make sure you wait a moment before attempt to fill the store with the localStorage data

something like

   ...
   if (window.localStorage.data) {
     setTimeout(() => {
       store.commit('data/setData', JSON.parse(window.localStorage.getItem('data')))
     }, 500)
   }

Working example is available on Netlify and code on GitHub

you can use vuex-persistedstate for saving in localstorage

Array.push Returns the length of the Array after insertion, In your case, it overrides the data Array to Number when you make a mutation. Do like the following..

export const state = () => ({
  data: []
})

export const mutations = {
  addItemToData (state, item) {
    state.data.push(item)
    // OR 
    state.data = [...state.data, item]
  },
  setData (state, data) {
    state.data = data
  },
}

And also make sure, you have data in localStorage.

 try { // handles if any parsing errors
   const data = JSON.parse(window.localStorage.getItem('data')
   store.commit('data/setData', data)
 } catch(err) {
   console.log('JSON parsing error', err)
 }
 
Related