Issue with Vuex store not being updated when called from promise resolution

I am facing an issue with my Vue.js application where I have an array called items bound to a Vuex data store and exposed as a computed property using the mapGetters helper. In the created() hook of the component, I make a REST API call to update this array. The Vuex action used for this task returns a promise that accesses the API and updates the items array before resolving. However, when I try to access items after the promise resolves, it is empty even though it should be populated by the API response. What could be causing this unexpected behavior?

Here are the relevant parts of the code:

Component:

  computed: {
    ...mapGetters({
      items: 'allHistoryItems'
    }),
// ...
  created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
  }

Action:

  fetchList: ({ commit }) => {
    return new Promise((resolve, reject) => {
      fetchList().then(response => {
        commit(types.FETCH_LIST, response.data)
        resolve(response)
      })
    })
  }

Although the API response can be accessed from the component, the items array remains empty. Could it be that reactivity does not occur until after the promise has resolved?

Answer №1

In summary

created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
}

Once the created method is invoked, it performs:

this.$store.dispatch('fetchList')

directly followed by

console.log(this.items)

This sequence happens without delay, and when

this.$store.dispatch('fetchList')
resolves, the .then method is called with an arrow function to handle console.log(this.items), which would otherwise return undefined

modify it to

created () {
    this.$store.dispatch('fetchList').then(() => console.log(this.items));
}

Additionally - improving efficiency by eliminating the promise constructor anti-pattern:

fetchList: ({ commit }) => fetchList() 
    .then(response => {
        commit(types.FETCH_LIST, response.data);
        return response;
    }
);

Answer №2

It seems like the new Promise construction you added is unnecessary. Check out this example below to see if it achieves what you need:

var store = new Vuex.Store({
  state: {
    hero: []
  },
  mutations: {
    updateHero (state, payload) {

      state.hero = payload
    }
  },
  actions: {
    async loadHero ({commit}, payload) {
      var response = await fetch('https://swapi.co/api/people/1/')
      commit('updateHero', await response.json())
    }
  }
})

new Vue ({
  el: '#app',
  store,
  computed: {
    hero () {
      return this.$store.state.hero
    }
  },
  methods: Vuex.mapActions(['loadHero'])
})
[v-cloak] {
  display: none;
}
<div id="app">
  Hero name is: <span v-cloak>{{ hero.name }}</span><br>
  <button @click="loadHero">Load hero personal data</button>
</div>

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

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

"Enhance your database by incorporating HTML link clicks through AJAX integration with PHP and MySQL

After browsing through similar questions and attempting to implement it on my website, I'm facing an issue where the expected functionality is not working as intended. When users click on a link, there is no response in the console, and the database r ...

Utilizing both a named function and an arrow function as event handlers in React

Can you spot the issue in the code snippet below? export default function App() { const [count, setCount] = useState(0); return ( <div className="App"> <h2>{count}</h2> <button onClick={() => { ...

Managing two variables in C# Controller and View

I am facing an issue with the two variables in my controller class. The first variable, currentUserId, is supposed to store the user currently logged into the website. The second variable, currentRoomId, should track the chat room the user is in. The probl ...

Encase the event handler within JQuery

Here's an example of inputs with OnBlur event handlers: <input name="abc" tabIndex="5" class="datetime" onblur="if (CheckMode(this))__doPostBack('abc',''); else return false;" /> Now, in JQuery Form ready function, I want ...

Techniques for passing state values in Vuex post requests

I am working on a project where I need to collect data using get and set methods for my form. The goal is to post the states to an API. However, I am wondering how I can organize or group the states in order to pass them to an action. Any suggestions? st ...

Vue & Quasar: Exploring methods to access files (specifically zip files) located outside of the Quasar project directory

I am completely new to Vue and Quasar, and I'm currently attempting to reload a file within a Vue page, specifically in the script section within a mounted() block. My attempts at loading the file have been unsuccessful so far: let baseL = require ...

[Vue alert]: "Maximum" property or method is not declared in the instance but is being referenced during the rendering process

Here is my custom Vue component: Vue.component("product-list", { props: ["products", "maximum-price"], template: ` <div> <div class="row d-flex mb-3 align-items-center p-3 rounded-3 animate__animate ...

Make a call to a remote node.js server using an ajax request

My setup involved a basic nodejs server (including CORS) : var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var port = 8001; http.listen(port, ...

Custom pagination for next/previous links in Django REST framework

When it comes to backend operations, I have integrated the PageNumberPagination as the DEFAULT_PAGINATION_CLASS. Since I am utilizing vue.js along with fetch, there is no need for me to include the entire URL structure provided by django-rest-framework: " ...

Unable to proceed due to lint errors; after conducting research, the issue still remains

I'm still getting the hang of tslint and typescript. The error I'm encountering has me stumped. Can someone guide me on resolving it? I've searched extensively but haven't been able to find a solution. Sharing my code snippet below. (n ...

Vue Notice: Property or function does not exist on the instance but is referenced during rendering

In my Component tag, I have a defined model name like so: <b-table-column v-if="" field="columnName" v-slot="itemProps"> <SelectableAttribute :attr-name="props2.row.fieldClass&quo ...

Adjust the top position of a div element at regular intervals

How can I make the top position of an absolutely positioned div with children change every x seconds using jQuery? I tried using setInterval but it only changes once. Here is my code: .com_prices { width: 100%; height: 100%; overflow: hidden; back ...

What is the best way to update a data value in one Vue Js component and have it reflected in another component?

I'm a newcomer to Vue Js and encountering an issue with changing data values from another component. Let's start with Component A: <template> <div id="app"> <p v-on:click="test ()">Something</p> </div> ...

Modifying the image height in a column using Bootstrap and JSON data

My webpage is dynamically generating images from a JSON file through a JavaScript file. However, the images are displaying at different heights, and I want each column to adjust to the height of the image to eliminate any gaps. Particularly, data with the ...

Could anyone help me locate the section in the MUI documentation that explains the correct syntax for the commented code lines I am working on?

Before proceeding, please note that the ThemeProvider with theme={theme} has already been provided. Now, I will share two distinct sets of code files. These files contain sections commented out because they are not functioning as intended when implementing ...

Retrieve an identifier from a web address and transmit it to the Laravel controller using VueJS

I'm currently facing an issue with submitting a form in my Vue application. The route I am working with is: http://cricketstats.test/en/dashboard/players/z2d4ca09a7/india/941/runs In this URL, the number 941 represents the player's ID. I need to ...

tips for extracting a specific attribute value from an XML document

Within my C program, I am working with the following XML data: <apStats><command chart_num="0">750</command><command chart_num="1">400</command></apStats> . $.ajax({ type: "POST", dataType: "xml", url: ge ...

Typescript raises an error when providing a potentially null value (that is not null) to an unnamed callback function

When dealing with a property that starts as null, how can I pass it to an anonymous callback function expecting a non-null value without TypeScript throwing errors? I've tried wrapping the function call in an if statement to check for null at the cal ...

Creating a bold portion of a string

My task involves dynamically creating <p> elements within a div based on the contents of my codeArray, which can vary in size each time. Instead of hard-coding these elements, I have devised the following method: for(i=1;i<codeArray.length;i++) ...

Managing an Angular timer: Starting and resetting it via the controller

Is there a way to start a timer when the user clicks on the recordLogs method and reset the timer when the user clicks on the stopLogs method? According to the angular-timer documentation, we should be able to use the timer-stop and timer-clear methods to ...