vuex-module-decorators
vuex-module-decorators copied to clipboard
Error "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation
Let me repeat: I did all according Accessing modules with NuxtJS explanations.
Store Module:
import { Action, Mutation, VuexModule, Module } from 'vuex-module-decorators';
@Module({
stateFactory: true,
name: "AUTHENTICATION__STORE_MODULE"
})
export default class AuthenticationStoreModule extends VuexModule {
private _token: string | null = null;
@Action
public async signIn(formData: { userId: string, password: string }): Promise<void> {
console.log("Called!");
const token: string = await new Promise(
(resolve: (token: string)=> void): void => {
setTimeout(() => { resolve('mock-token'); }, 2000);
});
console.log(token);
}
// ...
}
TypeScript types validation is all right. However, await authenticationStoreModule.signIn(formData)
does not work.
Component:
import { Vue, Component, Prop } from 'vue-property-decorator';
import VueReferencesInspector from '~/utils/VueReferencesInspector';
import { authenticationStoreModule } from "~/store/";
interface IElementUiForm extends Vue {
validate: (validationResult: (valid: boolean)=> void)=> void;
}
@Component
export default class extends Vue {
// ...
private onSubmit(): void {
// ...
try {
console.log('~~~');
console.log(authenticationStoreModule);
console.log(authenticationStoreModule.signIn(formData));
await authenticationStoreModule.signIn(formData);
this.$router.push('/admin');
} catch (error) {
this.dataIsBeingSubmittedNow = false;
}
});
}
}
console.log
s are;
As you see authenticationStoreModule
and authenticationStoreModule.signIn
are not undefined. However, console.log("Called!");
did not output, so action signIn
has not been called.
Once npm install
done,
- Execute
npm run dev
- go to page
http://localhost:3000/admin/login
- Try to login
You will see same console errors as in image.
Try:
@Module({
name: 'auth',
stateFactory: true,
namespaced: true,
})
For Nuxt usage you should match the filename and namespace of your module, so this module should be in ~/store/auth.ts
.
Thank you for the answer. It works for me; you may close this issue.
For Nuxt usage you should match the filename and namespace of your module, so this module should be in ~/store/auth.ts.
Was I miss this in documentation, or it is not documented yet?
Faced the issue as @TokugawaTakesi, so, @danielroe how we do namespace if my modules located under ~/store/modules/auth.ts
?
@webcoderkz Either move the module to ~/store/auth.ts
, move it out of the ~/store
directory entirely, or pass it the namespace modules/auth
.
Sorry, but where do we pass a custom namespace name?
Bottom of this page: https://github.com/championswimmer/vuex-module-decorators has an example for SSR usage (Nuxt), but there module is located under ~/store/modules/MyStoreModule.ts
and they call it as usually, so there's an error in documentation?
https://championswimmer.in/vuex-module-decorators/pages/advanced/namespaced.html
I already read that, thanks. My question was - how to use getModule(moduleName, this.$store)
inside a component with namespaces ~/store/modules/auth.ts
@webcoderkz I believe the answer is there. In your case:
@Module({ namespaced: true, name: 'modules/auth' })
But I may be misunderstanding your question.
my custom module (~/store/modules/settingsModule.ts):
import { Module, VuexModule } from 'vuex-module-decorators'
@Module({
name: 'modules/settingsModule',
namespaced: true,
stateFactory: true
})
export default class settingsModule extends VuexModule {
public test: string | undefined = process.env.CMS_URL
}
Using this module in a component:
public env = getModule(settingsModule, this.$store).test
Throws an error, Cannot read property 'test' of undefined
@webcoderkz Hm, not sure. Can you share a repro?
FYI: I no longer use vuex-module-decorators
but I'm very happy to take a look. :smiley:
@danielroe why don't you use it anymore? There's better alternatives to it?
@webcoderkz I think it's great - but I had to abandon because of this issue. However, a fix has now been merged and hopefully will be released soon. :smiley:
@danielroe Do you have any example of the solution?
@MisaelMa The solution to what?
Same issue is here. I changed module name matching with file name and move @/store/modules/user.ts to @/store/user.ts. However it doesn't work...
My code is here.
login.vue
import { createComponent, reactive } from '@vue/composition-api'
import { userStore } from '@/store'
....
setup() {
const state = reactive<State>({
email: '[email protected]',
password: 'pass'
})
const login = () => {
// eslint-disable-next-line no-console
console.log('userStore', userStore)
userStore.Login(state.email, state.password)
// root.$router.push("/")
}
return {
state,
login
}
}
....
utils/store-accessor.ts
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import { User } from '~/store/user'
// eslint-disable-next-line import/no-mutable-exports
let userStore: User
function initialiseStores(store: Store<any>): void {
userStore = getModule(User, store)
}
export { initialiseStores, userStore }
None of the solutions proposed here work for me either. I've recreated the issue in this repo:
https://github.com/qelix/nuxt-vuex-module-decorators-repro
Steps to reproduce:
- Clone repo, run
yarn && yarn dev
- Open
localhost:3000
- Open dev tools to find
[vuex] unknown mutation type: test/setTest
in console as proof that it doesn't work
Or just use Codesandbox: https://codesandbox.io/s/github/qelix/nuxt-vuex-module-decorators-repro
It is a simple reproduction of the issue, containing only a minimal configuration. I did everything according to the docs and the comments in this issue. Still can't get it to work, though.
Am I missing anything?
It took me some trial and error, and the documentation & examples don't mention this at all, but it seems that you have to export default
your module classes. See my minimal example that seems to work correctly.
Thanks a lot dude, I just tested it in my project and it works like a charm!
Having to use default exports is kind of a letdown but it's still better than being forced to use the deprecated classic store mode.
@danielroe I have my module in "module/home.ts" and I namespaced according to your suggestion and my namespace looks like:-
@Module({ namespaced: true, stateFactory: true, name: 'modules/home' })
But now I am not able to dispatch my action from this module
store.dispatch('modules/home/loadHome')
the action is not dispatching. Is there a way to dispatch my action inside "modules/home/loadHome"
@akashlama1998 As above, I recommend keeping your modules in the store folder if you are using Nuxt, because that is where Nuxt expects them.
I don't use this package any more, however, so apologies if that isn't of more help.
@danielroe Its Ok.. Thanks for the reply.. I already moved my modules to ~/store
.
I have documented some approaches to find out the optimum approach in this ticket: https://github.com/sniperadmin/qms-nuxt-ts/issues/17
@webcoderkz I believe the answer is there. In your case:
@Module({ namespaced: true, name: 'modules/auth' })
But I may be misunderstanding your question.
thinks It bothered me for two hours
This might be the solution. For me exactly! Module name with namespace @/store/Vdp/main.ts
@Module({
name: 'Vdp/main',
namespaced: true,
stateFactory: true
})
export default class main extends VuexModule {}
Try:
@Module({ name: 'auth', stateFactory: true, namespaced: true, })
For Nuxt usage you should match the filename and namespace of your module, so this module should be in
~/store/auth.ts
.
That solved my issue, but shouldn't this be in docs ? I could make a PR updating the readme
[vuex] unknown local mutation type: signIn, global type: signin/signIn
// ~/store/signin.ts
import { Action, Module, Mutation, VuexModule } from 'vuex-module-decorators'
export const namespace = 'signin'
export interface SignInFormFields {
email: string
password: string
}
@Module({
name: namespace,
stateFactory: true,
namespaced: true,
})
export default class SignIn extends VuexModule implements SignInFormFields {
email = ''
password = ''
@Mutation
public setEmail(email: string) {
this.email = email
}
@Mutation
public setPassword(password: string) {
this.password = password
}
@Action
signIn() {
console.log('signIn action dispatched')
return Promise.resolve({
email: 'test',
})
}
}
// ~/pages/signin.vue
import { WrappedFormUtils } from 'ant-design-vue/types/form/form'
import { Component, namespace, Vue, Watch } from 'nuxt-property-decorator'
import {
namespace as signInStoreNamespace,
SignInFormFields,
} from '~/store/signin'
const SignInStore = namespace(signInStoreNamespace)
@Component({ layout: 'auth' })
export default class SignInFormFieldsPage extends Vue {
form!: WrappedFormUtils
@SignInStore.State((state: SignInFormFields) => state.email)
public _email!: string
@SignInStore.Mutation
public setEmail!: (email: string) => void
get email(): string {
return this._email
}
@SignInStore.State((state: SignInFormFields) => state.password)
public _password!: string
@SignInStore.Mutation
public setPassword!: (password: string) => void
get password(): string {
return this._password
}
@SignInStore.Mutation
public signIn!: () => void
handleSubmit(e: MouseEvent): void {
e.preventDefault()
this.form.validateFields((err) => {
if (!err) {
this.signIn()
}
})
}
}
Mutations works fine but Actions don't