⚠️ This lesson is retired and might contain outdated information.

Call a Root Vuex Mutation or Action from within a Module in TypeScript

Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 7 months ago

Everything in a Vuex Module is local to itself: the State, Mutations, Actions, Getters. But sometimes you need to call something from the outside. This lesson shows how you can call an external Mutation and Action from within a module in TypeScript.

Aside from modules, we can also have our rootState mutations, actions, and getters. Let's write account state. TypeScript is complaining because the rootState doesn't have account property, and it's inferring it from the modules.

You go to LoginModule, you see there we are setting the rootState to second parameter of the module type. To fix it, go to types and add account property as a number to the rootState. Now let's try it on mutation. Call it sum, and it will take the state and sum it up by one.

The way we can trigger a real mutation from a module is by using an action. If we go to the todos module, we had defined an action there to add that todo asynchronously, and here we commit an app todo mutation.

From here, if we write commit sum, we would be triggering a todos/sum mutation because this module is in that space. In order to fix that, we can provide a third parameter which is annotate, and there defined root:true.

In that way, we'd be triggered with the namespace. Let's try this. We add an assigned todo here, and we'll see that the sum mutation has been triggered and the count state has been increased. The same applies to other modules, mutation, or actions.

For example, you could say login/login, and you will be triggering the login mutation from the login module. Let's try this again, and you'll see the mutation is triggered, and we see up there the name.

In order to dispatch actions, the contest parameter of an action give us a dispatch function. It has the same signature than commit. First parameter will be the action name, the second the payload, and in the third we can indicate root:true, so it will be triggered without the namespace.

F.
F.
~ 5 years ago

Hi Alex, Great series. Thanks for putting it together. When I try to define the "state" object in the Vuex.Store instance in @/store/index.ts, I get the following error in VS Code for "state":

"Type '{count: number;}' is not assignable to type 'RootState | (() => RootState) | undefined. Type '{ count: number;)' is missing the following properties from type 'RootState': todos, login ts(2322) index.d.ts(91,3): The expected type comes from the property 'state' which is declared here on type 'StoreOptions<RootState>"

The only way I knew how to solve for this is to open types.ts and make todos and login optional under the RootState interface:

export interface RootState { count: number; todos?: TodoState; login?: LoginState; }

But, this seems like the wrong way to handle this. Did you encounter this at any point along the way? I'm curious as to your thoughts on this, although the example I recognize is somewhat contrived.

Thanks! -fermin

F.
F.
~ 5 years ago

test

Aviel
Aviel
~ 5 years ago

the better approach of it is export initState of todos/login and add them to the rootState import { initState as loginState } from "./login"; import { initState as todosState } from "./todos";

export default new Vuex.Store<RootState>({ state: { count: 0, todos: todosState, login: loginState }, modules: { todos } });

Markdown supported.
Become a member to join the discussionEnroll Today