Why does Vue.js Vuex dispatch an action when importing module stores into a helper file?

I recently developed an application using Vue.js. The app is divided into several modules, each corresponding to a specific route and containing a main component with numerous sub-components/children. Every module has its own store, actions, mutations, getters, and API calls that are dispatched in the created() hooks of components to retrieve necessary data.

Here is a glimpse of my app's structure:

https://i.sstatic.net/umsQ8.png

Candidates.vue

created() {
    this.$store.dispatch('$_candidates/getAllCandidates');
  },

/modules/candidates/_store/actions.js

import api from '../_api';

const getAllCandidates = (context) => {
  api.fetchAllCandidates
    .then((response) => {
      context.commit('ALL_CANDIDATES_FETCHED', response.data.candidate_list);
    })
    .catch((error) => {
      // eslint-disable-next-line
      console.error(error);
    });
};

/modules/candidates/_api/index.js

import { fetchData } from '@/helpers';

const allCandidatesEndpoint =
  'https://myapiendpoint.io/candidates/list/all';
const fetchAllCandidates = fetchData(allCandidatesEndpoint, 'get');

export default {
  fetchAllCandidates,
};

In the beforeCreate() hook of App.vue, I have a helper function to register all of the application modules in one go. I do this by importing the module stores into the helper file and then registering them. Here is my helper file:

helpers.js

import axios from 'axios';
import { store } from '@/store/store';

import candidatesStore from './modules/candidates/_store';
import dashboardStore from './modules/dashboard/_store';
import eventsStore from './modules/events/_store';
import loginStore from './modules/login/_store';

function fetchData(endpoint, requestType, requestBody) {
  const apiToken = store.state.apiToken;
  delete axios.defaults.auth;
  return axios.request({
    method: requestType,
    data: requestBody,
    url: endpoint,
    headers: {
      'server-token-id': apiToken,
    },
  })
    .then(response => response)
    .catch(error => error);
}

/* Register all of the Vuex modules we'll need to manage application state */

function registerVuexModules() {
  store.registerModule('$_candidates', candidatesStore);
  store.registerModule('$_dashboard', dashboardStore);
  store.registerModule('$_events', eventsStore);
  store.registerModule('$_login', loginStore);
}

function unregisterVuexModules() {
  store.unregisterModule('$_candidates', candidatesStore);
  store.unregisterModule('$_dashboard', dashboardStore);
  store.unregisterModule('$_events', eventsStore);
  store.unregisterModule('$_login', loginStore);
}

export {
  fetchData,
  registerVuexModules,
  unregisterVuexModules,
};

...and I import it into App.vue like this:

beforeCreate() {
  registerVuexModules();
},

However, when I import each module, it triggers an unexpected API call, resulting in a 401 error. This behavior persists even after commenting out parts of helpers.js, confirming that the issue lies with the imports rather than the functions themselves.

The peculiar aspects for me include:

  1. API calls are attempted on every reload of the login page, even before the top-level components of modules are created;

  2. Vue-dev-tools fails to track the dispatching of corresponding actions;

  3. Removing all store imports from the helper file stops these phantom API calls.

I attempted lazy-loading components through vue-router to address this issue but experienced no success. Although the bundle size reduced, the unwanted API calls persisted. Here is how I implemented lazy loading:

/router/index.js

import Vue from 'vue';
import Router from 'vue-router';
import axios from 'axios';

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

/* Lazy load all of the components required for the routes */

const Login = () => import(/* webpackChunkName: "login" */
  '@/modules/login/Login');

const Dashboard = () => import(/* webpackChunkName: "dashboard" */
  '@/modules/dashboard/Dashboard');

...

const router = new Router({

  routes: [
    {
      path: '/',
      name: 'root',
      component: Login,
    },
    {
      path: '/login',
      name: 'login',
      component: Login,
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: Dashboard,
      beforeEnter: (to, from, next) => {
        guard(to, from, next);
      },
    },
...

If anyone can shed light on this perplexing behavior or point out any oversights on my part, it would be greatly appreciated.

Answer №1

Based on my observation, it appears that you have the following line of code:

const fetchAllCandidates = fetchData(allCandidatesEndpoint, 'get');

Essentially, this means that each time you use import, the fetchData function is executed and the results are returned.

Perhaps what you intended to do was something like this instead.

const fetchAllCandidates = function ()
{
  return fetchData(allCandidatesEndpoint, 'get');
}

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

Vue.js Ajax call is throwing a bizarre error: TypeError - str.replace function not recognized

Recently, I encountered a puzzling error message: vue-resource.common.js Uncaught TypeError: str.replace is not a function while working on an ajax call to retrieve some data: export default { data: () => ({ recipes: [] }), ready() { ...

order the numbers in an array to form the largest possible number

Suppose you have an array of numbers and you need to arrange them in a way that results in the largest possible value. For example, if the array consists of {54, 546, 548, 60}, arranging them as 6054854654 would yield the largest value. var maxCombine = ( ...

How to manage print preview feature in Firefox with the help of Selenium in the Robot Framework

Attempting to select the 'cancel' button in the print preview page on Firefox has proven to be a challenge. Despite my efforts, I am unable to access the element by right-clicking on the cancel option. Interestingly, Chrome allowed me to inspect ...

Is the toString() method explicitly invoked by Number() if the value is not of type number or string? (such as a function)

Looking for clarification on the behavior of parseInt() compared to the Number() constructor called as a function. I want to confirm if this is reliable and if there's an official reference to support it. Below is sample code: let adder = (function ...

Execute a click event on a single button within a specified CSS class

When a button with the class of "my-button-class" is clicked on a page, I have JavaScript code set up to execute the logic defined in doSomething(). However, the issue I am facing is that the doSomething() function is triggered for every button with that c ...

What is the best way to make an element fixed vertically in a mobile browser while also enabling horizontal scrolling?

When using a Desktop browser, I have found a javascript code that allows me to vertically fix an element while still enabling horizontal scrolling. The element is repositioned with each scroll event. You can test this out by trying both horizontal and vert ...

The pause and restart buttons are malfunctioning and are not functional

My goal is to create a stopwatch using JavaScript that can start and stop the timer. I want to store the time data in my MySQL database when the user presses the stop button. However, I am facing issues with the pause buttons not functioning properly. f ...

Error in Webpack: JSX elements that are adjacent must be enclosed within a wrapper tag

After adding a new component and integrating it into my Main component, I encountered an error when running webpack. The error message displayed was: "Adjacent JSX elements must be wrapped in an enclosing tag" Below is the snippet of code where the iss ...

How to turn off autocomplete for v-text-field in Vuetify

I'm using Vuetify's v-text-field component and I am trying to disable autocomplete. Even though I have included autocomplete="false", which is the correct syntax according to online sources, I am still seeing autocomplete suggestions. A ...

Jquery Visualization Chart not displaying

I am struggling to get the jquery visualization to work properly. Although the table and caption appear fine, there is no data showing up in the chart. I've carefully followed the example and searched for any issues, but I can't identify what&apo ...

Develop a fresh Typescript-driven sql.js database

I'm in the process of converting my JavaScript code to TypeScript. One of the libraries I rely on is sql.js. I have successfully installed the corresponding typing for it, but I am facing a roadblock when it comes to creating the database. Here is ho ...

Can a new webpage be created without requiring a separate HTML file extension?

Currently working on an assignment that requires creating various pages for a website. I currently have multiple HTML files where I link to each one to open the pages, such as Bagel and Bagel.html. Is there a more effective and efficient way to achieve t ...

Issue with JQuery plugin functionality when utilized repeatedly on a single page

Creating a unique JQuery plugin called grid2carousel has been my recent project. The plugin is designed to transform content displayed in a Bootstrap-style grid on desktop devices into a functional carousel on smaller screens. Although the plugin function ...

Setting up a div as a canvas in Three.js: Step-by-step guide

Is there a way to adjust the JavaScript in this three.js canvas example so that the scene can be contained within a specific div element on a webpage? Here is the example: https://codepen.io/PedalsUp/pen/qBqvvzR I would like to use this as the background ...

Populating an HTML form using a Node.js server

I am looking for a way to automate filling an HTML form's input fields, submitting it, and retrieving the body of the page. After some research, I came across a module called form-scraper. However, when I tried implementing it, I encountered the follo ...

Tips for passing a page as an argument in the function parameter of the page.evaluate() method?

I keep running into this issue when I pass the page as an argument: TypeError: Converting circular structure to JSON --> commencing at object with constructor 'BrowserContext' | property '_browser' -> object with const ...

activating the submit button depending on the user input

My goal is to create a form with a textarea and a submit button that can be enabled or disabled based on whether there is any input in the textarea. I have confirmed that both the submit button and content are being selected correctly (I'll provide a ...

Getting the total number of child elements in a web page using Selenium web-driver with Node.js

I've been looking everywhere, but I can't seem to find the answer Here's my HTML code: <form id="search_form_homepage" > ... <div class="search__autocomplete" style="display: block;"> &l ...

Managing multiple sets of data in a structured form similar to an array

How Do I Send Form Data as an Array? Take a look at the code snippet below. I'm having trouble setting the index in product_attribute['index must be here']['key'] <tr v-for="index in attributes"> <td class="text-left ...

What's the best way to showcase certain data from a JSON object in a structured table format?

{"symbol":"DRREDDY","series":"EQ","openPrice":"3,132.00","highPrice":"3,229.90","lowPrice":"3,132.00","ltp":"3,206.35","previousPrice":"3,153.25","netPrice":"1.68","tradedQuantity":"74,165","turnoverInLakhs":"2,379.33","lastCorpAnnouncementDate":"18-Jul-20 ...