How can one efficiently make API requests using Vuex?

Being new to both Vue Webpack and Vuex after transitioning from the Ember world, I have set up my Vue Webpack app with Vuex using vue-resource in two different files:

/src/store/api.js

import Vue from 'vue';
import { store } from './store';

export default {
  get(url, request) {
    return Vue.http
      .get(store.state.apiBaseUrl + url, request)
      .then(response => Promise.resolve(response.body))
      .catch(error => Promise.reject(error));
  },
  post(url, request) {
    return Vue.http
      .post(store.state.apiBaseUrl + url, request)
      .then(response => Promise.resolve(response))
      .catch(error => Promise.reject(error));
  },
  // Other HTTP methods removed for simplicity
};

The above api.js file is then imported into my /src/store/store.js file as shown below:

import Vue from 'vue';
import Vuex from 'vuex';
import Api from './api';

Vue.use(Vuex);

// eslint-disable-next-line
export const store = new Vuex.Store({
  state: {
    apiBaseUrl: 'https://apis.myapp.com/v1',
    authenticatedUser: null,
  },

  mutations: {
    /**
     * Updates a specific property in the store
     * @param {object} state The store's state
     * @param {object} data An object containing the property and value
     */
    updateProperty: (state, data) => {
      state[data.property] = data.value;
    },
  },

  actions: {
    usersCreate: (context, data) => {
      Api.post('/users', data)
        .then(response => context.commit('updateProperty', { property: 'authenticatedUser', value: response.body }))
        // eslint-disable-next-line
        .catch(error => console.error(error));
    },
  },
});

Although the functionality works fine, there are a few issues that need to be addressed:

  1. I am unable to capture issues in the component to display toast messages or handle error states.
  2. If I have multiple APIs, it will require writing numerous actions in the store.js file, which is not efficient. While creating a standard action that accepts HTTP method, URL etc. could be an option, I am unsure if this is a good practice.

What would be the best approach to overcome these challenges? How can I effectively monitor AJAX success or failure states within the component where the action is dispatched? What are the recommended practices for making API calls when utilizing Vuex?

Answer №1

To ensure proper functionality, your action must return a Promise. Currently, your code only calls Api.post without returning it, causing Vuex to be left out of the loop. Refer to the example in the Vuex documentation for guidance on Composing Actions.

By returning a Promise, the action caller can then utilize the then() method as shown below:

this.$store.dispatch('usersCreate').then(() => {
  // Handle API success
}).catch(() => {
  // Handle API failure
});

When organizing your actions, remember that you are not obligated to place them all in the store.js file. Vuex allows for modules and namespacing. Learn more at https://vuex.vuejs.org/en/modules.html

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

Passing a value from a prop to a click event that is dynamically created within an SVG Vue.js

Currently, I am in the process of developing a map component using a JSON array and implementing a click event handler for each item. The objective is to toggle the CSS style to color the item when clicked, which is functioning as expected. However, my goa ...

Implementing a Multi-Page Application (MPA) using React, Vue, or another similar framework

I am currently exploring the realms of React and Vue frameworks in an effort to enhance my skills. While I have been able to construct simple single-page applications (SPAs) through online courses, I have yet to come across any resources pertaining to mult ...

"Excessive use of Javascript setInterval combined with frequent ajax calls is causing significant

I have integrated the setInterval() function into my JavaScript code to make an AJAX call every 2 minutes. However, I noticed that this is causing the website to slow down over time. The website is built using Node.js. After doing some research, I came acr ...

What steps can I take to ensure my CSS selector for the element is functioning properly?

Here is an example of some code: <html> <head> <style> .test{ background-color: red; p { background-color: yellow; } } </style> </head> <body> <div class="test"> ...

Using Javascript to test a specific item in an asp Listbox

Let's consider a scenario where there is ListBox1 containing the following listitem: <asp:ListItem Value="No.1">No.1</asp:listitem> In addition, we have a label for a test purpose: <asp:Label ID="lblLabel" runat="server" Text="Label ...

Creating an angular controller in a template based on certain conditions

When working with Angular.js, I'm attempting the following: index.html <div class="data-tabs-sms-scroll" ng-show="question.type == 'open'" ng-controller="AudioMessagesCtrl" ng-include="'/templates/audioMessages.html' ...

Data retrieved from the vue.js API seems to be consistently coming back

I am creating an API in PHP: <?php header('Access-Control-Allow-Origin: *'); header('Content-Type: application/json'); include '../DBconnect.php'; $rslt = $pdo->query("SHOW TABLES"); $songs_random['data& ...

Leveraging UseRouter.query Data in Next.js Content Display

I'm currently diving into routing in Next.js and running into an issue where the query values are not being included in the HTML response. Despite recognizing that isReady is false and the return is happening before the variables are set, I'm uns ...

Detecting duplicate key values within a JSON array using Angular.js

I am seeking a solution in Angular.js to verify if duplicate key values exist within a JSON array. Below is a breakdown of my code: var result=[{ "email":'<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ec8dac8b ...

Spring application encountering 404 error following nginx request

My Vue application is connected to two different backend services. One of them uses SpringBoot, which is currently not compatible with nginx. The configuration in my nginx.conf.template file includes: location /apcc { proxy_pass ${APCC_BACKEND_URL}; ...

Incorporating object into main function of VueJS root component

I have integrated VueJS into my HTML template for an application. When a button is clicked, it passes the object of a component to its root in the following manner: <button v-on:click="$root.savePlan(dataObj)"></button> The dataObj is passe ...

Ways to address a buffered data problem in Websocket Rxjs. When trying to send a message, it is not being received by the server and instead is being stored in a

Currently, I am utilizing Websocket Rxjs within my application. The connection is successfully established with the server, and upon subscribing to it, all data is received in an array format. However, when attempting to send data back to the server, it se ...

Implement a jQuery slideshow with a full background image, aiming to set up a clickable link on the final image of the

Could someone please help me with a query I have regarding a background image slide show using jQuery code? I have set up a slide show with multiple images and would like to make the last image clickable. Is it possible to achieve this specific functionali ...

Is the Bootstrap Carousel not automatically scrolling when navigating back in Angular?

Whenever I launch my Angular application, the image slider implemented using Bootstrap carousel functions properly. However, upon navigating to another view and returning to the image slider, it no longer auto-slides. Even though I can manually navigate th ...

steps for repairing a scoreboard

Is there a way to make my scoreboard increase by +1 point instead of +10? In my JavaScript code, I used intervals as it was the only solution that worked: let scoreInterval = setInterval(updateScore); let score = 0; function updateScore() { var poin ...

Attempting to manipulate information within the @click event handler embedded within a v-for loop

I am using a v-for loop to select dialog boxes that I want to open. <v-card @click="page.model = true"> In this code, page.model is being used as the v-model for a v-dialog component. data() { return { dialog1: false, dia ...

The Navigation Bar in Vue Component Renders Incorrectly due to Bootstrap Integration

I am facing an issue with my Bootstrap navbar not displaying correctly within my Vue component. It is appearing as a stacked greyed out button, almost like it's assuming it's on a small device. https://i.sstatic.net/yoPvO.png You can find the c ...

When using Node.js with Mongoose, you will receive a single object value instead of multiple values in an array

data=[{ locId: '332wn', locadetails: [ { loc: 'ny', status: true }, { loc: 'ca', status: null ...

What to do when encountering the error "Exceeded Maximum Call Stack Size in vue-router"?

Hello there, I am facing the following error: [vue-router] uncaught error during route navigation: vue-router.esm.js:1897 RangeError: Maximum call stack size exceeded at String.replace (<anonymous>) at resolvePath (vue-router.esm.js:597) ...

What is the best way to make a select tag read-only before the Ajax request is successful

Is there a way to make a select tag read-only before an Ajax success? I tried using this code, but it didn't work: $("#tower").prop('readonly', true); Then I tried this alternative, but I couldn't get the value from the select tag: ...