Tom
Tom

Reputation: 1457

Update : Mutation recieve the store, not the state

This post has an update, see the first answer

So, first of all, I did search for similar problems (and found a few threads) but nothing solved my problem. I'm trying to use quasar framework for the first time and maybe I got lost somewhere in the namespaces or something.

So, first, some info : +I don't have any error when compiling with ESLint
+I don't have any error in my javascript console at runtime
My problem is :
+My actions and mutation do save something in the store, but not where it should (see screenshot at end of post)
+My getter does not seems to work, and is displayed as "undefined" in the vue dev tool

My store is organized like that :

+store [folder]  
+ index.js  
+ app-utils [folder]  
--+ index.js  
--+ getters.js  
--+ actions.js  
--+ mutations.js  
--+ state.js  

Code of the root index.js :
import Vue from 'vue' import Vuex from 'vuex'

import appUtils from './app-utils'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    appUtils
  }
})

export default store

Then, in the folder 'app-utils' : Code for index.js :

import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'
import * as actions from './actions'

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}

Code for state.js :

export default {
  state: {
    currentPageTitle: 'Hello'
  }
}

Code for getters.js :

export const getPageTitle = (state) => {
  console.log('GET TITLE: ' + state.currentPageTitle)
  return state.currentPageTitle
}

Code for mutations.js :

export const setPageTitle = (state, newPageTitle) => {
  console.log('MUTATION SET TITLE: ' + newPageTitle)
  state.currentPageTitle = newPageTitle
}

export const deletePageTitle = (state) => {
  console.log('MUTATION DELETE TITLE')
  state.currentPageTitle = ''
}

Code for actions.js :

export const setPageTitle = (context, newPageTitle) => {
  console.log('ACTION SET TITLE: ' + newPageTitle)
  context.commit('setPageTitle', newPageTitle)
}

export const deletePageTitle = (context) => {
  console.log('ACTION DELETE TITLE')
  context.commit('deletePageTitle')
}

The code from where i am trying to access it (int the getPageTitle computed field):

<template>
  <q-page>
    <q-resize-observable @resize="onResize" /> TITLE : {{getPageTitle}}
    <div class="row">
    </div>
  </q-page>
</template>


import { mapGetters, mapActions } from 'vuex'

export default {
  data: () => ({
    pageSize: {
      height: 0,
      width: 0
    }
  }),
  mounted () {
    this.setPageTitle('Template manager')
  },
  destroyed () {
    this.deletePageTitle()
  },
  computed: {
    ...mapGetters('appUtils', [
      'getPageTitle'
    ])
  },
  methods: {
    ...mapActions('appUtils', [
      'setPageTitle',
      'deletePageTitle'
    ]),
    onResize (size) {
      this.pageSize = size
    }
  }
}
</script>

<style>
</style>

Finaly, screenshot from the vue plugin , you can see the value has been set upon triggering the mounted() hook, but not in the 'state', and the getter is undefined.

Screenshot from the vue dev plugin

Upvotes: 2

Views: 1138

Answers (2)

Tom
Tom

Reputation: 1457

Update: solved, see selected answer

So I solved my problem. It would appear thatthe first argument sent to my mutation is not the state, but the store itself. So :

This does not work

export const setPageTitle = (state, newPageTitle) => {
 console.log('MUTATION SET TITLE: ' + newPageTitle)
 state.currentPageTitle = newPageTitle
}

This works

export const setPageTitle = (store, newPageTitle) => {
 console.log('MUTATION SET TITLE: ' + store.newPageTitle)
 store.state.currentPageTitle = newPageTitle
}

Is this normal behaviour ? The doc seems to say the first argument is supposed to be the state itself.

Upvotes: 0

Wyatt Arent
Wyatt Arent

Reputation: 588

Your state object looks like this:

export default {
  state: {
    currentPageTitle: 'Hello'
  }
}

And that whole thing is being passed to your getter state parameter. That entire exported object is your state, not the "state" property within it. So you have two options:

Option one: Update your getter to access the nested "state" property within your state:

export const getPageTitle = (state) => {
  console.log('GET TITLE: ' + state.state.currentPageTitle)
  return state.state.currentPageTitle
}

Option two (Probably what you really want to do): change your state object to not have the "state" property.

export default {
  currentPageTitle: 'Hello'
}

Upvotes: 3

Related Questions