0
votes

i am working with the q-table in an app with vuex. Adding the popup edit to the table and editing a fields content in the browser, i get these errors and warnings in the console (see below).

The app works as expected, but is throwing those errors, but is throwing these funny error messages. I think it is a necessary learning to not just disable strict mode but to understand what is the right way to do this.

How can i trigger a vuex mutation on user input into this q-popup-edit in a way that the browser will not throw these error messages?

I have tried suppressing the warning which makes no real sense.

I have read the documentation https://quasar.dev/vue-components/popup-edit

which holds no references to any callback function for on user input

...
<template>
  <div class="q-pa-md">
    <q-table
      title="Bewerber"
      :data="data"
      :columns="columns"
      row-key="id"
      binary-state-sort
      separator="cell"
      selection="single"
      :selected.sync="selected"
    >
    <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-checkbox dense v-model="props.selected" />
          </q-td>
          <q-td key="id" :props="props">
            {{ props.row.id }}
          </q-td>
          <q-td key="added" :props="props">
            {{ props.row.added }}
            <q-popup-edit v-model="props.row.added" buttons @save="saveRow(props.row)">
              <q-input type="text"  v-model="props.row.added" dense autofocus counter />
            </q-popup-edit>
          </q-td>

...



vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."

(found in <Root>)
warn @ vue.runtime.esm.js?2b0e:619
logError @ vue.runtime.esm.js?2b0e:1884
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
run @ vue.runtime.esm.js?2b0e:4564
update @ vue.runtime.esm.js?2b0e:4536
notify @ vue.runtime.esm.js?2b0e:730
reactiveSetter @ vue.runtime.esm.js?2b0e:1055
set @ vue.runtime.esm.js?2b0e:1077
callback @ list.vue?994d:645
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
Vue.$emit @ vue.runtime.esm.js?2b0e:3882
emitValueFn @ QInput.js?27f9:145
emitValue @ QInput.js?27f9:162
onInput @ QInput.js?27f9:126
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
vue.runtime.esm.js?2b0e:1888 Error: [vuex] do not mutate vuex store state outside mutation handlers.
    at assert (vuex.esm.js?2f62:90)
    at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:774)
    at Watcher.run (vue.runtime.esm.js?2b0e:4562)
    at Watcher.update (vue.runtime.esm.js?2b0e:4536)
    at Dep.notify (vue.runtime.esm.js?2b0e:730)
    at Object.reactiveSetter [as address_line_1] (vue.runtime.esm.js?2b0e:1055)
    at Proxy.set (vue.runtime.esm.js?2b0e:1077)
    at callback (list.vue?994d:645)
    at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
    at VueComponent.invoker (vue.runtime.esm.js?2b0e:2179)

EDIT: (after Guillaume Meral's comment below, thx for pointing out this missing info)

The data prop is set like this:

computed: {
    data: function () {
      return this.$store.getters['candidate/getCandidates']
    }
  },

I expect to be able to catch these input events and call a vuex action to mutate the state properly and thereby get rid of the errors / warnings. But there seems to be little documentation about this, maybe i am overseeing something?

This is my first question on Stackoverflow. Please let me know if i need to update my question or specify anything in more detail.

Thanks for your help @community.

**EDIT: ** my first attempted solution was to add setters to the computed property like described in the link posted by Guillaume Meral below.

I have implemented this change, looking like this:

  computed: {
    data: {
      // getter
      get: function () {
        return this.$store.getters['candidate/getCandidates']
      },
      // setter
      set: function (newData) {
        this.$store.dispatch('candidate/updateCandidateList', newData)
      }
    }
  },

with an action

export function updateCandidateList (state, data) {
  state.commit('setCandidates', data)
}

and a mutation

export function setCandidates (state, data) {
  if (data) {
    state.candidates = JSON.parse(JSON.stringify(data))
  } else {
    state.candidates = null
  }
}

and state

export default {
  candidates: []
}

Still the warnings persist in the console

[Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."(found in <Root>)

vue.runtime.esm.js?2b0e:1888 Error: [vuex] do not mutate vuex store state outside mutation handlers.
    at assert (vuex.esm.js?2f62:90)
    at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:774)
    at Watcher.run (vue.runtime.esm.js?2b0e:4562)
    at Watcher.update (vue.runtime.esm.js?2b0e:4536)
    at Dep.notify (vue.runtime.esm.js?2b0e:730)
    at Object.reactiveSetter [as added] (vue.runtime.esm.js?2b0e:1055)
    at Proxy.set (vue.runtime.esm.js?2b0e:1077)
    at callback (list.vue?994d:93)
    at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
    at VueComponent.invoker (vue.runtime.esm.js?2b0e:2179)

sidenote: also adding JSON.parse(JSON.stringify(data)) anywhere wont help ^^

I don't get what is wrong here. Let me know if you do, please.

SOLUTION

Mapstate solved the problem for me. It does suppress the errors on every keystroke done in the text input field before hitting the save button.

  computed: {
    ...mapState('candidate', {
      data: state => state.candidate
    })
  },
1
Without seeing the way props.row.added it is not possible to give a definitive answer. However i suspect that it is directly assigned with a part of the state of the store. What you need to do is using a computed property with a getter and a setter part like here : vuejs.org/v2/guide/computed.html#Computed-Setter In the getter you get the value from the store, in the setter, you commit a mutation or dispatch an action.Guillaume Meral
The data prop is added like this: computed: { data: function () { return this.$store.getters['candidate/getCandidates'] } } So basically i have to add getter and setter to this to make it work (it is only the getter now implicitly)?mwx
I have implemented the proposed changes, but the error message persists. I have updated the question with some more details.mwx
Next step for you would be to cut down the interactions with vuex to see where the problem comes from precisely. You could try to replace the data by a static array like in the quasar doc to see if you still have an error. (By the way i really don't like the name data, it is confusing because vue components also have a data property.Guillaume Meral
I will give it a try and provide the result here in the next few daysmwx

1 Answers

0
votes

SOLUTION

Mapstate solved the problem for me. It does suppress the errors on every keystroke done in the text input field before hitting the save button.

  computed: {
    ...mapState('candidate', {
      data: state => state.candidate
    })
  },