What is the most efficient approach to completing everyday tasks directly in a Vuex store?

Currently, I am working on making API calls from within a Vuex store action object. Here's an example of one of my actions:

/**
 * Check an account activation token
 *
 */
[CHECK_ACTIVATION_TOKEN] ({commit}, payload) {
  Api.checkActivationToken(payload.token).then((response) => {
    if (response.fails()) {
      return commit('NEW_MESSAGE', {message: responses.activation[response.code]})
    }

    return commit('SET_TOKEN')
  })
}

I have multiple methods like this for different actions. What I want to do is display a loader while each API call is in progress and hide it once the response is received. One way to achieve this is by including the loader logic in each action like this:

/**
 * Check an account activation token
 *
 */
[CHECK_ACTIVATION_TOKEN] ({commit}, payload) {
  commit('SHOW_LOADER')
  Api.checkActivationToken(payload.token).then((response) => {
    commit('HIDE_LOADER')
    if (response.fails()) {
      return commit('NEW_MESSAGE', {message: responses.activation[response.code]})
    }

    return commit('SET_TOKEN')
  })
}

However, having to add these SHOW_LOADER/HIDE_LOADER commits in every API call is repetitive. I would prefer to centralize this functionality so that the loader handling is automatically applied to all API calls without the need for additional lines in each action.

The API I am using is a client layer built on top of Axios. I tried importing the store into the client layer or where the Axios events are triggered to handle the loader visibility centrally, but encountered a circular reference issue because of how the client layer is instantiated within the vuex module.

Is there a way to achieve what I'm aiming for through hooks or events that I may not be aware of?

Answer №1

After coming across a discussion on GitHub and hearing Evan You's thoughts on decoupling, I decided to take a different approach to addressing this particular issue.

I realized that by making the API layer directly dependent on the store, I was creating tight coupling between the two components. As a result, I opted to handle the SHOW and HIDE functionality within each component where the store commits are triggered. Here's an example:

/**
     * check the validity of the reset token
     *
     */
    checkToken () {
      if (!this.token) {
        return this.$store.commit('NEW_MESSAGE', {message: 'No activation token found. Unable to continue'})
      }

      this.showLoader()

      this.$store.dispatch('CHECK_ACTIVATION_TOKEN', {token: this.token}).then(this.hideLoader)
    },

In my case, I created methods in a Master Vue component that other components could inherit from, bypassing direct Vuex commits. This allowed me to trigger showLoader when necessary and manage the completion process with promises, calling hideLoader accordingly.

By doing this, I successfully removed presentation logic from both the store and API layers, keeping them separated in their respective domains.

If anyone has alternative suggestions or insights on this matter, I am open to hearing them.

Special thanks to @wostex for contributing to the conversation!

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

Partial data sent through Ajax to PHP file

Encountering a peculiar issue with Ajax where the entire string data is not being sent to the php script. Here is the string: "<p class="MsoNormal" style="text-align:justify"><b><u><span lang="DE" style="font-size:10.0pt;mso-bidi-fon ...

Tips on serializing two arrays into JSON format and incorporating them in an AJAX request

I have a task where I need to retrieve all the names and details associated with a specific reference number. To accomplish this, I am using a while loop. However, I am unsure of how to encode these values in JSON format so that I can use them in AJAX for ...

Why won't NextJS Image elements render on iOS 16 when they are not in the viewport initially?

I opted to implement NextJS for enhanced routing capabilities and image optimization. However, I encountered an issue with certain images failing to load properly on iOS devices. The problem arises within a scrollable horizontal container featuring Product ...

Transmit an Array using Ajax and retrieve it on an ASP Classic page

I am facing a challenge where I need to pass an array using AJAX on an ASP page. After trying to send it as GET method and checking the data being received, I noticed that only the LAST record of the array is being processed by ASP. How can I successfu ...

Receiving feedback from an Ajax request

When attempting to retrieve the responseText from an AJAX call created in plain JavaScript, there seems to be an issue where Firebug can detect the request but cannot obtain a reference to the responseText. Below is the code for the function: function ge ...

When attempting to add a variable using the next() function, I encountered an error with the BehaviorSubject. The error message displayed was "this.count.next is not a function"

In my Angular service, there is a variable called count that I need to monitor for updates. Whenever this count variable is updated, I want to assign its new value to another variable in a separate component. import {BehaviorSubject} from "rxjs/BehaviorSu ...

Manipulating the vueObject.dataItem variable in Vue JS directly affects the underlying Vue data item

I’ve encountered a troublesome behavior in my projects. Here is a simplified explanation of the issue at hand. I am eager to understand why this occurs and how I can prevent it. I have included Vue in the head section of my website: <script src="http ...

Peer-to-peer Ajax image sharing

Currently, I'm utilizing Ajax to fetch images from a remote server. Initially, I attempted this by directly using the URL of the remote server - resulting in the returned image being a string (given that's how Ajax communicates). To rectify this, ...

My type is slipping away with Typescript and text conversion to lowercase

Here is a simplified version of the issue I'm facing: const demo = { aaa: 'aaa', bbb: 'bbb', } const input = 'AAA' console.log(demo[input.toLowerCase()]) Playground While plain JS works fine by converting &apo ...

Prevent the countdown timer from resetting every time I refresh the page

Whenever I refresh my page, the timer starts over. I want it to pick up from where it left off until it reaches 0. This is my JavaScript code for handling the timer: var target_date = new Date().getTime() + (1000*3600*48); // set the countdown date var ...

Using an external HTML file to import a template into Vue.js single file components

I've been tackling a Vuejs project that involves using vue-property-decorator in single file components. I'm trying to figure out how to import the template from an external HTML (or different) file, but so far I haven't found a solution. I& ...

Can Mongoose be integrated into a Next.js API environment?

My current project involves creating a website for my sister to showcase and sell her artwork. Utilizing Next.js, I have set up the framework where the website displays the artwork by fetching an array from a database and iterating through it. Let's ...

"Discover the magic of jQuery: Unveiling the hidden div with one simple CSS visibility change

I want to implement a functionality on my screen where the Previous button is hidden initially and only becomes visible when the user clicks the Next button. I have set the CSS property for the Previous button to hide it by default, but despite using an if ...

Avoid re-rendering the page in Nuxt when adjusting dynamic parameters

My page has two dynamic parameters that trigger the fetch method to run again when the URL params are changed. I want to avoid this behavior. Fetch Method: async fetch() { await this.getFlightResult(); } Get Result Method: async getResult() { th ...

What is the best way to insert a Button within a Tab while ensuring that the indicator remains in the appropriate tab?

Is it possible to include a button inside a Tab? When I click on "Homepage", the tab switches correctly with the indicator showing on the right tab. However, when I click on "Profile", the indicator moves to the logout button instead. How can I fix this ...

Combining HashRouter and anchor navigation in React: A guide to seamless page navigation

I am currently utilizing the HashRouter functionality from the library react-router-dom. The issue I am facing is when attempting to link to a specific div on the same page using an anchor tag: <a href="#div-id"> Link to div </a> In ...

With Ionic, you can use one single codebase for both iPad and iPhone

I currently have a complete app developed using ionic and angularjs that is functioning well on iPads and Android devices. Now we are looking to launch it for iPhones and Android smartphones with some design modifications. Is there a method to achieve th ...

Troubleshooting checkboxes malfunction in custom tools on Laravel Nova

Just started using Laravel Nova and currently playing around with custom tools. Within my custom tool, I've integrated a checkbox in the tool.vue component using the Vue checkbox component provided by Laravel Nova. <checkbox/> Although the ch ...

How can I troubleshoot email validation issues in Vue.js?

<button type="submit" class="register-button" :class="(isDisabled) ? '' : 'selected'" :disabled='isDisabled' v-on:click=" isFirstScreen ...

Nextjs unexpectedly displays blank page upon fetching data from Firebase Firestore without any error messages

I am currently facing an issue when trying to retrieve page details from Firebase Firestore using getStaticPaths and getStaticProps in my Next.js project. Despite following the code structure correctly, I am encountering a scenario where the page appears e ...