Steps for isolating AXIOS requests in a Vuex store

My Vuex store file appears very typical and contains the following code:

//store.js
import Vue from 'vue';
import Vuex from 'vuex';


Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    loading: true,
    companyBasicInfo: [

    ]
  },
  mutations: {
    getCompanyBasicInfo: (state, res) => {
      state.companyBasicInfo.push(res);
    },
    changeLoadingStatue: (state, loading) => {
      state.loading = loading;
    }
  },
  actions: {
    getCompanyBasicInfo: context => {
// AXIOS REQUESTS GO HERE
    }
  }
});

The axios request in my getCompanyBasicInfo() action functions perfectly.

My Objective

I aim to separate my AXIOS requests into another file in order to streamline my store.js file.

My Attempt

To achieve this, I created a file named requests.js with the following content:

import axios from 'axios';

export default GET_COMPANY_DETAILS = () => {
  setTimeout(() => {
    axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
      context.commit('getCompanyBasicInfo', res.data);
      context.commit('changeLoadingStatue', false);
    }).catch(e => {
      console.log(e);
    });
  }, 3000);
};

Afterward, I attempted to import this file into my store.js file like so:

import requests from './requests';

Issue

However, I faced difficulty when trying to call requests.GET_COMPANY_DETAILS(); within the getCompanyBasicInfo() action. It seems that the method in the requests.js file cannot be accessed.

Error Notification

An error is displayed in the console stating

Uncaught ReferenceError: GET_COMPANY_DETAILS is not defined
.

Answer №1

Issues with Exporting

When utilizing the

export default GET_COMPANY_DETAILS
, the import of requests will result in the GET_COMPANY_DETAILS function being imported.

This enables a direct call to requests().

Refer to the MDN documentation on export for more information on the various options available.

An Effective Method to Export an API

A correct approach to exporting an API should look like:

// api.js
import axios from 'axios';

// initialize an axios instance with default settings
const http = axios.create({ baseURL: 'http://localhost:3000/' });

export default {
    getCompanyDetails(tradeKey) {
        // return the promise of the axios instance
        return http.get(`companies/show/${tradeKey}`)
            .catch(err => {
                // handle errors if needed
                console.log(err);
            });
    },
    anotherEndpoint() {
        return http.get('other/endpoint');
    }
};

You can export a default API as demonstrated above, or even utilize both named and default exports.

export function getCompanyDetails(tradeKey){ /*...*/ }
export default { getCompanyDetails }

In your store implementation:

import api from './api';

// ...

actions: {
    getCompanyBasicInfo({ commit }, key) {
        // Remember to return the Promise within the action
        return api.getCompanyDetails(key).then(({ data }) => {
            commit('getCompanyBasicInfo', data);
            commit('changeLoadingStatus', false);
        });
    }
}

The store-related code needs to be located within your actions section.

Enhance Isolation Further

I have provided an answer containing examples of axios-middleware and axios-resource, which aid in creating modules with single responsibilities.

You can utilize middleware to manage errors, while concentrating on endpoint configuration within resource classes.

Answer №2

To enhance the organization of your code, I recommend structuring it based on the recommended application structure outlined in Vuex documentation.

This approach will promote a clear separation of concerns and help to keep your store.js file concise and efficient.

Consider exporting functions individually instead of using default exports. This will allow you flexibility in exporting multiple functions from a single file like requests.js.

For example:

import axios from 'axios';

export function getCompanyDetails() {
  setTimeout(() => {
    axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
      context.commit('getCompanyBasicInfo', res.data);
      context.commit('changeLoadingStatue', false);
    }).catch(e => {
      console.log(e);
    });
  }, 3000);
};

export function someOtherApiMethod() {}

Instead of utilizing setTimeout within GET_COMPANY_DETAILS, consider returning the promise directly from Axios.

For instance:

 export function getCompanyDetails() {
    return axios
        .get('http://localhost:3000/companies/show/trade key egypt')
        .then(res => res.data)
};

Subsequently, integrate this promise into your action logic:

import { getCompanyDetails } from './requests';

actions: {
    getCompanyBasicInfo: context => {
        getCompanyDetails().then(() => {
            // implement mutations
        });
    }
  }

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

What ways can I leverage JavaScript to convert a provided array into multiple different arrays?

I am in need of a function that meets the following criteria: Given the dimensions of an array, return all possible combination arrays based on the given numbers. The length of the given array should be equal to the length of the array returned. The size ...

Guide on testing Vue prop updates with Jest

I'm a Jest beginner and I'm currently working on writing a test for my Vue application where I need to confirm that a child component emits an event and updates its prop value accordingly. To illustrate this, I have created a simple app with a c ...

You cannot add properties to an object within an async function

I am attempting to include a fileUrl property in the order object within an async function, but I am unable to make it work properly. My expectation is for the order object to contain a fileUrl property once added, but unfortunately, it does not seem to b ...

Is there a way to incorporate a fade-in effect when I trigger the expand function in this script?

I recently came across a jQuery plugin for expanding and collapsing content. I am interested in adding a fade-in effect to this plugin specifically when the EXPAND button is clicked. How can I accomplish this? $(document).ready(function () { var maxlines ...

Condition in SQL for searching full name with no specific order of first name or last name

How can I search for a column named fullname by filtering on firstname/lastname without specific order? In the following Javascript example, the query is invalid when searching by lastname: function getQuery(searchWord){ return `SELECT * FROM user WHERE ...

Error in Layout of Navigation Panel and Tabbed Pages

Working on a school project, I encountered a challenge. I found two useful solutions from the W3 website - a sticky navigation bar and the ability to include tabs on a single page for a cleaner presentation of information. However, when trying to implement ...

Troubleshooting: jQuery's append function does not seem to be functioning properly when trying

I am attempting to include a stylesheet in the head section of my page, but it seems that using 'append' is not getting the job done. Is there an alternative approach I should consider? Here is the code snippet: $('head').append(&apos ...

What is the best way to experiment with angular-ui-tinymce within a tabset using Plunker?

I am currently experimenting with angular-ui-tinymce by incorporating it into a Plunkr. Can anyone assist me in integrating the necessary files for angular-ui-tinymce into the Plunkr so that I can showcase its functionality? Currently, I have this Plunker ...

Is the alias name absolute or converted to AliasId when establishing a connection with Sequelize and Migrations?

In my Housing model, I have a sequelize association set up like this: Housing.belongsTo(models.User, {as : Owner}); When adding the column to the model and Migrations file with this association, will the table be named "Owner" exactly as the Alias, or "Ow ...

An error stating 'THREE.OBJLoader is not a constructor' has occurred, along with an 'Unexpected token {' message in OBJLoader and OrbitControls

Attempting to showcase an OBJ 3D model as a wireframe that can be interactively moved using OrbitControls in Three.js. Being new to three.js, I apologize if I'm overlooking something obvious. Successfully displayed a wireframe cube with OrbitControls ...

What is the best way to retrieve subreddit comments from a post using JavaScript?

Is there a way to retrieve subreddit comments from a post using the Reddit API as it suggests [/ r / subreddit] / comments / article? I attempted something similar to this: https://reddit.com/r/science/comments/qdfs2x/new_research_suggests_that_conservati ...

How do I incorporate global typings when adding type definitions to an npm module?

Suppose I create a node module called m. Later on, I decide to enhance it with Typescript typings. Luckily, the module only exports a single function, so the m.d.ts file is as follows: /// <reference path="./typings/globals/node/index.d.ts" /> decl ...

The execution of the code may encounter errors initially, but it generally runs without any issues on subsequent attempts

I recently developed a piece of code to ascertain whether a value in the database is null or not. Here's the snippet: var table; var active = false; function CheckActive(table){ this.table = "table" + table + ""; var db = window.openDatabas ...

Executing the command "node <app name>" does not result in any action

I am experiencing an issue with my bot app called "vgen.js". When I run the command "node vgen", the prompt/directory disappears and the cursor just blinks on the far left of the screen. I have been following instructions from a tutorial found here: https ...

Validating Range Constraints

I am facing a dilemma with my GridView that contains a textbox in one of its fields. To ensure that the user enters only a single character "x", I have implemented a range validator: <asp:TextBox ID="txtMP3Master" runat="server" Text='<%# Eval( ...

The Django project does not contain any JS script

Currently expanding my knowledge in Django and encountering an issue. The JS script is not being included in the Django project despite having the correct path. While the page itself with the graph block functions properly, the output of a round or bar cha ...

The variable fails to receive the AJAX response

Trying to retrieve the content of data.dat, I have utilized the following code. Below are the relevant files: main.js function getData() { var result; var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState ...

Refreshing the page reveals the complete local storage object

I've successfully created a todo list using Vanilla Javascript along with local storage. The todo list includes the following key-value pairs: key: todolist value: [[\"id:0\",\"title:buy groceries\",\"done:false\"], [&b ...

Guide to dynamically setting the title and background color of the navigation bar in React Navigation 5

In my current project, I am utilizing React Navigation Bar version 5 and have successfully set the title in App.js. However, I now need to change this title dynamically when the screen is rendered. I attempted to use this.props.navigation.navigate('Ex ...

Iterating through a JSON object to verify the presence of a specific value

I have a JSON Object and I am looking for a way in Angular 6 to search for the value "Tennis" in the key "name". Can you provide guidance on how to achieve this? { "id":2, "name":"Sports", "url":"/sports" "children":[ { "id":1, ...