No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Quasar, vuexfire and this._data.$$state error

    Help
    1
    2
    302
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • tlloyduk
      tlloyduk last edited by tlloyduk

      Hi all

      I know this is not strictly a Quasar issue (probably) but hoping someone has encountered the same problem before.

      Dev mode: spa
      Pkg quasar: v1.11.2
      Pkg @quasar/app: v1.8.6

      I’ve started using vuexfire in my Quasar app to make it easier to sync a Firebase document with vuex and all is fine when reading the document but I can’t make any changes in order to write back to Firebase. I must be missing something really simple here- I’m stuck! I have read the docs that vuexfire is only for reading because it is simple to write back using Firebase calls, but I can’t get that far due to:

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

      e952a0fd-586c-4d63-9298-f3ae211a0237-image.png

      Here’s my situation: I have the store set up as follows:

      main store/index.js

      export default function (/* { ssrContext } */) {
        const Store = new Vuex.Store({
          modules: {
            auth, customerConfig
          },
          mutations: {
            ...vuexfireMutations
          },
      
          // enable strict mode (adds overhead!)
          // for dev mode only
          strict: process.env.DEV
        })
      
        return Store
      }
      

      customerConfig is the store module that I’m binding to a Firebase document. I have an action in there:

      export const getCustomerConfig = firestoreAction((context, customerKey) => {
        console.log('[*] Binding to collection: customers document: %c' + customerKey, 'color: red;')
        return context.bindFirestoreRef('config', firebaseStore.collection('customers').doc(customerKey))
      })
      

      That works great. In my .vue file, I am then displaying an array from the document in a q-table, e.g. my document looks a bit like:

      {
      	"domains": [{
      			"domain": "test.com",
      			"useSpfRecord": true
      		},
      		{
      			"domain": "another.com",
      			"useSpfRecord": false
      		}
      	]
      }
      

      and I use a q-table to show the domains list…

      <q-table
            :title="data.length > 0 ? 'Domains (' + data.length + ')' : 'Domains'"
            :data="domains"
            :columns="columns"
            row-key="domain"
            :pagination.sync="pagination"
            no-data-label="No domains have been added yet"
          >
      

      and domains uses a getter in computed to return just the domains array from the document

      computed: {
          ...mapGetters('customerConfig', ['domains'])
        },
      

      This works great, my domains are listed in the table as expected.

      I then have a q-toggle in a table cell which I want to use to change the value of useSpfRecord in the domain object, e.g.

      <q-td key="useSpfRecord" :props="props">
                  <div>
                    <q-toggle :color="props.row.useSpfRecord ? 'green' : 'grey'" :value="props.row.useSpfRecord" @input="updateToggle(props.key, $event)" checked-icon="done" />
                  </div>
                </q-td>
      

      This calls an action where I plan to write back to the Firestore document with the change.
      However, as soon as I try and change the useSpfRecord property then I get the error

      export const updateDomain = firestoreAction(({ state }, payload) => {
        const customerRecord = { ...state.config } // <--- Copy of the Firebase document from vuex
        const domains = customerRecord.domains
      
        domains.forEach((domainCfg, idx) => {
          if (Object.prototype.hasOwnProperty.call(domainCfg, 'domain')) {
            if (domainCfg.domain.toLowerCase() === payload.key.toLowerCase()) {
              domainCfg['useSpfRecord'] = payload.val // <--- BOOOOM!!!!
            }
          }
        })
      })
      

      So I don’t even get the chance to write back to Firebase with a set call.

      Any thoughts or suggestions ?

      Thanks!

      tlloyduk 1 Reply Last reply Reply Quote 0
      • tlloyduk
        tlloyduk @tlloyduk last edited by

        Aarrrgghhhh finally the penny dropped after I read the error eleventy billion times. It was a layer-8 problem 🙂

        I was modifying the state from a Vuex action, not from a mutation handler

        I moved my code into mutations.js and changed my @input method to call the mutation directly, rather than trying to do it through an action which it doesn’t like.

        updateToggle: function (key, field, val) {
              this.updateDomainRecord({ key, field, val }) // <--- mutation
              this.updateDomainConfig(key) // <--- action
                .then(() => {
                  console.log('SUCCESS!')
                })
                .catch((error) => {
                  console.log('ERROR', error)
                })
            }
        
        1 Reply Last reply Reply Quote 0
        • First post
          Last post