Example of a floating undo bar using a dynamic function in a Vuex store module

Issue Overview

  1. Trigger the mutation or action of Vuex store module A to execute an external function. This external function can belong to another Vuex store module (e.g. B).
  2. A should store a reference to the external method (e.g. mutation or action from Vuex store module B) as it will be indirectly invoked at a later time.

In the example below:

  • A will represent
    RollbackActionFloatingPanelStoreModule
  • B will represent OtherStoreModule
  • The external function will be referred to as rollbackRemoveItem

Scenario (Use Case)

This floating undo panel allows users to revert their actions, but the undo functionality must be implemented. Since multiple types of user interactions need to be rolled back, the undo method needs to be specified each time.

https://i.stack.imgur.com/GBk2A.png

$ref is not suitable for TypeScript-based Vue applications, so using the $ref solution becomes necessary. I aim to offload the undo panel state and behavior entirely to a Vuex module, making the Vue component logic-free:

import { Vue, Component } from "vue-property-decorator";
import { getModule } from "vuex-module-decorators";

import template from "./RollbackActionFloatingPanel.pug";
import RollbackActionFloatingPanelStoreModule
    from "@Store/modules/AssociatedWithComponents/RollbackActionFloatingPanel";


@Component({ template })
export default class RollbackActionFloatingPanel extends Vue {
  private readonly relatedStoreModule: RollbackActionFloatingPanelStoreModule =
      getModule(RollbackActionFloatingPanelStoreModule);
}

Component template (pug language; svg icons are encapsulated within pug mixins)

transition(name="rollback_action_floating_panel")
  .RollbackActionFloatingPanel(v-show="relatedStoreModule.displayFlag")
    +Checkmark__Simple__Bold--MaterialDesignIcon.RollbackActionFloatingPanel-CheckmarkIcon
    .RollbackActionFloatingPanel-Text {{ relatedStoreModule.message }}
    button.RollbackActionFloatingPanel-Button(@click="relatedStoreModule.onClickRollbackButton")
      +Undo__Simple--MaterialDesignIcon.ButtonWithPrependedIcon-Icon
      | Undo
    button.RollbackActionFloatingPanel-Button.RollbackActionFloatingPanel-Button__Primary(@click="relatedStoreModule.dismiss")
      +Hide__StrikethroughEye__Filled--MaterialDesignIcon.ButtonWithPrependedIcon-Icon
      | Hide

The vuex store RollbackActionFloatingPanel only requires one public method: displayAndHideALittleLater. It could be called from other store modules or Vue components. The undo method implementation can be specified as a parameter (

displayAndHideALittleLater(payload: { message: string; onClickRollbackButton: Function; })
).

Despite being called in the template, methods onClickRollbackButton and dismiss cannot be restricted by TypeScript since they are not public.

import { VuexModule, Module, Mutation, Action } from "vuex-module-decorators";

import store, { StoreModuleNames } from "@Store/Store";

@Module({
  name: "VUEX_MODULE:UNDO_PANEL",
  store,
  dynamic: true,
  namespaced: true
})
export default class RollbackActionFloatingPanelStoreModule extends VuexModule {
  
  // Vuex module contents detailed here
}

Instructions for usage with another Vuex module:

import { VuexModule, Module, Mutation, getModule } from "vuex-module-decorators";
import store, { StoreModuleNames } from "@ProjectInitializer:Store/Store";
import RollbackActionFloatingPanelStoreModule
  from "@ProjectInitializer:Store/modules/AssociatedWithComponents/RollbackActionFloatingPanel";


@Module({
  name: "VUEX_MODULE:OTHER"
  store,
  dynamic: true,
  namespaced: true
})
export default class OtherStoreModule extends VuexModule {

  // Contents of the OtherStoreModule explained here.
}

Error details

https://i.stack.imgur.com/fxKTF.png

Error message displayed: ERR_ACTION_ACCESS_UNDEFINED: Attempting to access this.someMutation() 
or this.someGetter within an @Action? 
This is permissible only in dynamic modules. 
If not dynamic, utilize this.context.commit("mutationName", payload) and 
 this.context.getters["getterName"]
Error: Could not perform action onClickRollbackButton

This error occurs because all of my modules are dynamic, although the accuracy of the error message might be questionable. In reality, we invoke the rollbackRemoveItem mutation through the non-decorated function _onClickRollbackButton via the onClickRollbackButton action. Avoiding _onClickRollbackButton isn't straightforward since we need to retain the undo method implementation until the dismiss mutation is executed.

Attempt with static class field

@Module({
  name: "VUEX_MODULE:UNDO_PANEL",
  store,
  dynamic: true,
  namespaced: true
})
export default class RollbackActionFloatingPanelStoreModule extends VuexModule {

  // Content mentioned here for static class field attempt.
}

Same error persists.


Reproduction Case

I have created a reproduction case as a GitHub Repository which you can clone or download. To run the project, execute

npm i && npm run JavaScriptBuild
in the project directory after installing all dependencies. Once the build is complete, you can access the output at http://localhost:8081/

Answer №1

Have you tried using the rollbackRemoveItem method in your store?

You might want to consider something like the following code snippet:

connect() {
  const connection = getModule(Connection, this.$store);
  connection.testAction();
  this.$store.dispatch('Connection/rollbackRemoveItem');
}

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

Place an image at the top of the canvas at a specific location

Currently, I am in the process of reconstructing this specific website My approach involves working with React (similar to the aforementioned site) and utilizing the same cropper tool that they have implemented. For cropping, I am incorporating react-imag ...

Using Webpack to directly embed image paths in your code

I am working on a project that uses webpack and vue.js. I encountered an issue when trying to add an image to the vue template using src '/images/imageName.png', which resulted in a 404 error. How can I adjust the configuration to recognize absol ...

Filtering function that works without specific knowledge of keys

I'm working on a JavaScript method to filter a list dynamically without knowing the specific key (s). I've made some progress, but I'm stuck and not sure how to proceed. The foreach loop I have isn't correct, but I used it for clarity. ...

The issue of conflicting clickability between Vue row and href

Apologies for the confusion. I am dealing with an unusual question here. In my table setup, each row can be clicked using the iWasClicked function. However, the last column contains clickable images (href links), and I only want the images to be clickabl ...

performing an action using vuex in a component's method

I am facing an issue where I am trying to dispatch an action and retrieve the values passed into an input field. When I directly dispatch an action on a button, everything works perfectly fine: <button type="button" @click="store.dispatc ...

Export multiple variables at once

Within TypeScript, I have Class1 defined in class.ts, along with some functions from helper.ts and variables from variables.ts: For instance, the content of variables.ts is as follows: export const test1 = 'test1'; export const test2 = 0; expor ...

How to Pass a JSON Object to a Child Component in Angular and Display It Without Showing "[Object

Need help with my API call implementation. Here's a snippet from my Input component: Input.html <form (submit)="getTransactions()"> <div class="form-group"> <label for="exampleInputEmail1"></label> <input type="t ...

What is the best way to invoke a function in a functional React component from a different functional React component?

I need to access the showDrawer method of one functional component in another, which acts as a wrapper. What are some best practices for achieving this? Any suggestions or insights would be appreciated! const TopSide = () => { const [visible, se ...

Transitioning from angular 7 to the latest version 12

Upgrading from Angular 7 to 12 has presented a series of issues for me. The main problem seems to be with Angular Material. I am looking for a solution to this. ./src/app/material.module.ts:13:89-110 - Encounter Error: 'MatAutocompleteModule' ( ...

What is the proper method for updating the axios proxy URL dynamically?

In my main Vue file, I currently have this code snippet: export default axios.create({ baseURL: 'http://127.0.0.1', proxy: { '/api/': 'http://127.0.0.1', '/w0w/': 'http://192.168.1.12' } }) V ...

Sending new props when navigating back using $navigateBack

I created an overview page where users can view their results. They have the option to edit a value by clicking on the edit button, which navigates them to another page for making changes. However, upon returning to the overview page after editing, I notic ...

Looking for a way to connect a background image in Vue CLI?

When running the code below, I encounter an issue. The code runs properly but the images are not displaying and instead showing the URL as unknown. How can I fix this problem? The images definitely exist. <template> <div class="slider">< ...

Fixing the error "cannot call a function which is possibly undefined" in React and TypeScript

Seeking a resolution to the error "cannot invoke an object which can possibly be undefined" by utilizing react and typescript. What is the issue at hand? The problem arises when using the useContext react hook to create a variable (dialogContext) in compo ...

Implementing a props interface for conditions in styled components within a React application using Typescript

This specific component is created using React along with the "styled components" library to manage user input. In the case of invalid user input, the corresponding styles should be displayed as shown below (class invalid). Although this example functions ...

Avoid triggering onClick events on all rows when clicking, aim for only one row to be affected per click

I have a unique situation where I have a table containing rows with a button in each row. When this button is clicked, it triggers an onClick event that adds two additional buttons below the clicked button. The Issue: When I click on a button, the onClick ...

What is preventing me from utilizing a union type in conjunction with redux connect?

Below is a brief example of the code I am working on: import { connect } from "react-redux"; interface ErrorProps { error: true; description: string; } interface NoErrorProps { error: false; } type TestProps = ErrorProps | NoErrorProps; ...

Activate a function when the VueJS countdown timer hits zero

I've successfully created a countdown timer in the template that decrements a number perfectly. Now, I'm facing the challenge of triggering a function declared within the methods section once the countdown reaches 0. Despite attempting to check i ...

The "path" parameter must be a string data type in order to proceed. The value received is currently undefined

My current project is utilizing Angular 8 When I attempt to run 'ng build --prod', my project encounters errors. ERROR in The "path" argument must be of type string. Received type undefined The issue arose after adding "enableIvy": true to the ...

When an Angular service is created, its properties are not immediately configured

My current task involves testing an Angular (4.1) service that looks like this: @Injectable() export class JobService { private answerSource = new Subject<AnswerWrapper>(); answer$ = this.answerSource.asObservable(); answer(answer: AnswerWra ...

Creating a way for a Node and React application to share classes

I am in the process of developing a Node and React application, both implemented using TypeScript. The directory structure of my project is illustrated below: https://i.sstatic.net/914A1.png My query: Given that I am utilizing the same programming langu ...