Tips for creating a Vuex mutation without using asynchronous promises

I have a project underway that involves building an app using Vue.js, Vuex, and Firebase to update data from Firestore database to the state in mutations. Even though mutations are synchronous and promises (.then) are asynchronous, my current implementation seems to be working fine. However, I am unsure why it is still executing properly. Should I reconfigure mutations so that FB data is updated to the state without using a promise? Or could this setup be left as is? Below is the Vuex code for reference. Appreciate any insights!

import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase'
import db from '@/firebase/init'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    items: null
  },
  getters: {
    getItems: state => {
      return state.items
    }
  },
  mutations: {
    setAllUser: state => {
      const items = []
      db.collection('users').get()
      .then(snapshot => {
        snapshot.forEach(doc => {
          let userData = doc.data()
          userData.id = doc.id
          items.push(userData)
        })
        state.items = items
      })
    },
  actions: {
    setAllUser: context => {
      context.commit('setAllUser')
    }
  }
})


**SOLUTION**

import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase';
import db from '@/firebase/init'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    items: null
  },
  getters: {
    getItems: state => {
      return state.items
    }
  },
  mutations: {
    setAllUser: (state, items) => {
      state.items = items
    }
  },
  actions: {
    setAllUser: async context => {
      let snapshot = await db.collection('users').get();
      const items =[]
      snapshot.forEach(doc => {
        let userData = doc.data()
        userData.id = doc.id
        items.push(userData)
      })
      context.commit('setAllUser', items)
    }
  }
})

Answer №1

Consider moving your asynchronous code to actions:

{
  mutations: {
    setAllUser: (state, items) => state.items = items
  },
  actions: {
    setAllUser: async context => {
      let snapshot = await db.collection('users').get();
      let items = snapshot.map(doc => {
        let userData = doc.data();
        userData.id = doc.id
        return userData;
      });
      context.commit('setAllUser', items)
    }
}

But why should you do this?

  • For single responsibility: Mutations should only be responsible for setting the state.
  • Uncertainty about how vue-devtools will react if multiple mutations are triggered at once.
  • Mutations should rely solely on payload and state, without involving network/server responses.
  • Your colleagues may not expect mutations directly affecting the state from outside.

Why does it work?

  • The same principle applies when manually manipulating state with window.store.state.items = []: Vuex handles getters and updates to trigger DOM refresh.

P.S. Instead of using await, you can opt for promise.then within your action function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Injecting a service into an Angular constant is a straightforward process that involves

Is it possible to define a constant that utilizes the $locale service? Since constants are objects, injecting them as parameters like in controllers is not an option. How can this be achieved? angular.module('app').constant('SOME_CONSTANT&a ...

Guide on sending a form from a separate component upon clicking the OK button in a modal window using Bootstrap Vue

I've encountered a situation in my Vue app where I have a component called TodoForm that handles a basic form. I want to implement functionality using bootstrap-vue so that when the OK button within a bootstrap modal is clicked, the form is submitted. ...

Using ASP.NET Server Controls to Toggle Textbox Visibility Based on Dropdown Selection

What is the optimal method for displaying or hiding a textbox or an entire div section based on a user's selection from a dropdown menu? I am uncertain if this can be achieved with server controls, so would it require using standard client-side HTML c ...

There appears to be a syntax error in the Values section of the .env file when using nodejs

I have been working on implementing nodemailer for a contact form. After researching several resources, I came across the following code snippet in server.js: // require('dotenv').config(); require('dotenv').config({ path: require(&apos ...

AngularJS restructured the homepage to function as a shell page instead of the traditional index page

As a newcomer to angularJS, I am learning that it is typically designed for Single Page Applications. Most example logins I come across define the index.html as the main page, with the ng-view portion contained within. However, in my situation, the Login ...

Encountering CORS issue despite employing a CORS library

Encountering a CORS error while attempting to deploy my project on render using expressjs and react. The project functions smoothly on localhost, but changing the URLs to match the website results in this error: Access to XMLHttpRequest at 'https:// ...

Retrieve JSON data using AngularJS

Can someone guide me on how to make a GET request to my API endpoint and handle the JSON response in my code? Sample Controller.js Code: oknok.controller('listagemController', function ($scope, $http) { $scope.init = function () { ...

What is the best way to transfer information from my function to the data method?

I'm currently facing an issue with passing data from my API to the data method in Vue. data(){ return{ name:"" } }, methods: { getData(){ ...

Browsers seem to only respond to the FileReader onload event on the second try

Currently I am working on implementing in-browser image processing using HTML5 and encountering a strange issue specifically in Chrome. The problem lies with the onload event handler for the File API FileReader class, as the file is only processed correctl ...

Issue arises with asynchronous function outside of mounted lifecycle hook in VueJS

Identifying the Issue I encountered an issue while trying to create an external async function and assign its return value directly to a state variable. In addition, I passed firebase reference and store to this function to avoid importing them again in t ...

Utilizing ASCX to trigger JavaScript functions within an ASPX page

I created a user control named MyListSelect.ascx that contains a list of radio buttons... <%@ Control Language="C#" %> <select> <option disabled selected>Select Options</option> <option> option 1 </opti ...

What is the best way to store information in my express server using Angular?

After spending several hours on this issue, I am feeling stuck. Initially dealing with a CORS problem, I managed to solve it. However, my goal is to utilize $resource without creating a custom post method. My API follows RESTful standards where POST /artis ...

Update an existing item or add a new one if it is not already present

I am attempting to create a functionality similar to canva.com, where users can select images from the sidebar and drop them anywhere in the "div", allowing multiple images with individual positions. However, when I use setState(prevState=>{return [...p ...

Accessing XML data using Cross-Domain AJAX

New to this! I'm currently working on a client script that requires reading an XML file from another domain. I attempted to utilize JSONP, and while I receive a 200 response, the client is unable to access the data returned for some unknown reason. Tw ...

How to retrieve the value of a table row by clicking with the mouse using jQuery?

I am having an issue with my table data display. Each row in the table is assigned a unique ID, which corresponds to the value of the tr-tag. My goal is to log this ID in the console when a table row is clicked. Here is the table: $.getJSON(`http://local ...

Steps for changing the language in KeyboardDatePicker material ui

Currently, I am utilizing material ui on my website and leveraging the KeyboardDatePicker API with successful results. The only issue is that the months' names and button text are displayed in English, whereas I would prefer them to be in Spanish. Des ...

Node.js Express refuses to serve .js files with absolute URLs

I have encountered a perplexing issue with two files located in /public/widget, namely help.html and help.js http://localhost:8084/widget/help.html When entered into the address bar, it functions normally However, when attempting to access http://local ...

Thinking of hosting an event centered around Google Maps?

Are there specific event listeners for panning or zooming the Google Map, in addition to the mouseover, mouseout, and click events? UPDATE: I tried using 'center_changed', but it didn't work the way I expected. Whenever I move the mouse ov ...

React components receive props as an empty array when they are being passed to the component

I am passing a state to a component as a prop in the following way: componentDidMount() { axios.get("path/to/data") .then(result => { this.setState({ receivedData: result.data, }); ...

Are there equivalent npm variables like (`npm_config_`) available in yarn console scripts?

Utilizing variables in custom npm commands is possible (example taken from ): { "scripts": { "demo": "echo \"Hello $npm_config_first $npm_config_last\"" } } Can this functionality also be achieved ...