Can Vuex mapActions be utilized within a module that is exported?

Is it possible to utilize Vuex mapActions from an external module imported into a component?

I am working on standardizing a set of functions in a vue.js web application. My goal is to import these functions into each component and pass necessary values for them to operate. I am using Vuex for state management. Currently, each component independently calls these functions when loaded, duplicating the process.

I aim to refactor this by consolidating all functions into one module and importing it into the components as needed. This module utilizes mapActions as part of its functionality. Below are snippets of code: Vue component, module script, and Vuex action:

Vue component:

// Calling the imported function
if (!this.queued){
   timer.updatePage(this.pagination, this.orders);
}

Module script (advance.js):

import { mapActions } from 'vuex';

let currentComp = {
   name: 'purchase',
   date: null,
   start: false
}

const timer = {
   ...mapActions(['currentComponent']),
   updatePage(pagination, order) {
      currentComp.name = 'nextComponent';
      this.currentComponent(currentComp);
   }
}
export default timer;

Vuex action code:

// Within the actions section:
currentComponent({
        commit
    }, comp) {
        console.log(comp);
        commit('setCurrentComponent', comp);
}

// Within the mutations section:
setCurrentComponent: (state, comp) => {
        state.currentComponent = comp.name;
        return state;
    }

When running the component with the imported function, an error occurs:

vuex.esm.js?2f62:870 Uncaught TypeError: Cannot read property 'dispatch' of undefined
    at Object.mappedAction [as currentComponent] (vuex.esm.js?2f62:870)
    at eval (advance.js?935c:37)

Removing 'this' from 'this.currentComponent' results in another error:

advance.js?935c:37 Uncaught ReferenceError: currentComponent is not defined
    at eval (advance.js?935c:37)

Thanks in advance for any advice or pointers.

Answer №1

mapActions provides a shortcut for generating a method that resembles the following:

currentComponent() {
   this.$store.dispatch('xxx')
}

When executing this method, the context of this is set to timer. However, since timer does not possess a $store property, it results in the error message "

Cannot read property 'dispatch' of undefined
". To rectify this issue swiftly, you can change the context of this to the component that actually owns the $store property. This can be achieved by passing the component as a third parameter in the updatePage function and binding currentComponent accordingly.

// component code
timer.updatePage(this.pagination, this.orders, this);

// advance.js
const timer = {
   ...mapActions(['currentComponent']),
   updatePage(pagination, order, component) {
      currentComp.name = 'nextComponent';
      this.currentComponent.bind(component)(currentComp);
   }
}

It is advisable to utilize a mixin for handling this scenario more effectively.

import { mapActions } from 'vuex';

let currentComp = {
   name: 'purchase',
   date: null,
   start: false
}

const timerMixin = {
   methods: {
       ...mapActions(['currentComponent']),
       updatePage(pagination, order) {
          currentComp.name = 'nextComponent';
          this.currentComponent(currentComp);
       }
   }
}
export default timerMixin;

Within your component, import the timerMixin and incorporate it as a mixin. Subsequently, these methods will be directly accessible within your component and can be invoked with a slight adjustment to your existing code.

if (!this.queued){
   this.updatePage(this.pagination, this.orders);
}

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

Patience is key when awaiting a state update in the Vue.js router's beforeEnter guard

My goal is to control access to specific pages in my vue router. Instead of embedding authentication logic in each component, I would prefer to have a 'hasUserAccess' check in my child-routes only where it's necessary. { path: 'admi ...

"The issue persists where the Vuex action fails to update the state every time it is called from

Struggling with filtering my blog posts using Vuex. I update the data based on the category name extracted from the URL on route change and pass it as the action payload. This logic is implemented within a method called in 'mounted'. The computed ...

Ordering an Array of JavaScript Objects in a Custom Sequence (utilizing pre-existing methods)

Imagine we have an array of objects: ["c", "a", "b", "d"] Is there a way in ECMAScript or through a third-party JavaScript library to rearrange the objects in the first array to match the order specified by the second array, all within one line or functi ...

How can users change the displayed Twitch channel?

My coding skills aren't the greatest, especially when it comes to something like this. I've tried searching for a solution with no luck, so I apologize if this is too basic or impossible. I have a simple page that loads up Twitch with a predefin ...

Using Blob to save CSV file on Safari

Here are the codes I am using to generate a download link for users to download a .csv file from my website. var link = document.createElement("a"); link.id = "csvDwnLink"; window.URL = window.URL || window.webkitURL; var csv = "\ufeff" + CSV, b ...

The read more button is not functioning properly when used in conjunction with the <br>

Can someone help me debug an issue I'm facing with my code? I have created an HTML tab that contains multiple DOM elements, each with a "Read More" button. Everything works fine when it's just plain text, but as soon as I add tags within the p ...

Vue alert: A duplicate key with the value of '10' has been identified. This could potentially lead to an issue with updates

I've been encountering a persistent error that I can't seem to resolve: [Vue warn]: Duplicate keys detected: '10'. This issue is causing an update error in my application. Despite trying the following steps, the error continues to appe ...

Javascript - Could anyone provide a detailed explanation of the functionality of this code snippet?

Ever since joining a new company 9 months ago, I've been encountering this line of code in JavaScript. It seems to work fine and I've been incorporating it into my coding style to align with the previous developers. However, I'm not entirely ...

Tips for adding your artistic touch to photos

I'm currently facing a challenge in creating a chart that overlaps an image. The bars and text on the chart are displaying perfectly when I remove the background image. However, I'm struggling to get the bars and text to appear on top of the imag ...

The JSON response may be null, yet the data flows seamlessly to the success function in

Currently, I am facing an issue with Ajax. The situation is as follows: I want to check if a user is available by typing their email address. Therefore, I have created a JavaScript function that includes an Ajax script for this purpose. Here is my code: $ ...

What are the steps to add 8 columns to the second row in my table?

this is an example of HTML code that showcases a table structure with multiple rows and columns. You can view the full code snippet here. The table includes different sections, such as section1, section2, section3, and section4 in the first row (tr). In t ...

Performing an XMLHttpRequest in the same JSP file using Javascript

I am working on a JSP file that contains three dropdown boxes labeled "countries", "regions", and "cities". My goal is to populate the regions based on the selected country, and the cities based on the selected region. I have managed to achieve this using ...

Do not include any punctuation when counting within a textfield

I'm working on a textfield with a length validator, but I need to exclude punctuation from the character count. Here's what I currently have: <v-text-field v-model="note" maxlength="255" dense> </v-text-f ...

What is the best way to incorporate global variables within Vue JS components?

I am currently working on creating a web-app using Vue JS. I have come across the concept of Single File components(.vue files) which seems like a great way to create components. However, I am looking to avoid using any node modules. That's when I dis ...

modify the getters in the Vuex store

As I attempt to modify the data retrieved using getters, I find myself creating a dynamic form for editing values. While I can display the data successfully, I am still uncertain about how to update the data using getters. This is my edit form: You can a ...

Creating a Paytm payment link using API in a React Native app without the need for a server

Suppose a user enters all their details and the total cost of their order amounts to 15000 rupees. In that case, the app should generate a Paytm payment link for this amount and automatically open it in a web view for easy payment processing. Any suggesti ...

What is the process for inserting a personalized class into a td element within slot items?

Is there a way to conditionally add a class to a td element? <template slot="items" slot-scope="props"> <td> {{ props.item.id }} </td> <td :class="{'users-table__item--delete': props.i ...

Stopping the papaparse streaming process once a certain number of results have been achieved

Currently, I am utilizing the PapaParse library to parse a large CSV file in chunk mode. During my data validation process, I encountered an issue where I was unable to stop streaming the data once validation failed. I attempted to halt the streaming by ...

Utilizing JavaScript or jQuery to adjust the cursor pointer value based on user input

Issue: Need help with live updating of input value to range input pointer [Check out my CodePen for reference][1] Adjust upper range input pointer based on lower range input pointer ][2] I am currently working on a range-to-range calculator for a book ...

<JavaScript> changing the color of hyperlink in d3.js - <Organizational Chart>

screenshot The width of the link can be adjusted, but the color remains unchanged. I have attempted various solutions series.links.template.setAll({ strokeWidth: 2, strokeOpacity: 0.5, color: am5.color('#ffffff'), links: ...