Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation #179

Open
TokugawaTakeshi opened this issue Sep 18, 2019 · 27 comments

Comments

@TokugawaTakeshi
Copy link

TokugawaTakeshi commented Sep 18, 2019

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.logs are;

image

As you see authenticationStoreModule and authenticationStoreModule.signIn are not undefined. However, console.log("Called!"); did not output, so action signIn has not been called.

📁Repro Project

Once npm install done,

  1. Execute npm run dev
  2. go to page http://localhost:3000/admin/login
  3. Try to login

You will see same console errors as in image.

@TokugawaTakeshi TokugawaTakeshi changed the title "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation" "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation Sep 18, 2019
@TokugawaTakeshi TokugawaTakeshi changed the title "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation Error "[vuex] unknown action type:" in Nuxt, however I did all exactly according "Accessing modules with NuxtJS" documentation Sep 18, 2019
@danielroe
Copy link
Contributor

danielroe commented Sep 22, 2019

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.

@TokugawaTakeshi
Copy link
Author

TokugawaTakeshi commented Sep 23, 2019

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?

@avxkim
Copy link

avxkim commented Nov 4, 2019

Faced the issue as @TokugawaTakesi, so, @danielroe how we do namespace if my modules located under ~/store/modules/auth.ts?

@danielroe
Copy link
Contributor

danielroe commented Nov 4, 2019

@webcoderkz Either move the module to ~/store/auth.ts, move it out of the ~/store directory entirely, or pass it the namespace modules/auth.

@avxkim
Copy link

avxkim commented Nov 4, 2019

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?

@danielroe
Copy link
Contributor

danielroe commented Nov 4, 2019

@avxkim
Copy link

avxkim commented Nov 4, 2019

I already read that, thanks. My question was - how to use getModule(moduleName, this.$store) inside a component with namespaces ~/store/modules/auth.ts

@danielroe
Copy link
Contributor

danielroe commented Nov 4, 2019

@webcoderkz I believe the answer is there. In your case:

@Module({ namespaced: true, name: 'modules/auth' })

But I may be misunderstanding your question.

@avxkim
Copy link

avxkim commented Nov 4, 2019

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

@danielroe
Copy link
Contributor

danielroe commented Nov 4, 2019

@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. 😃

@avxkim
Copy link

avxkim commented Nov 4, 2019

@danielroe why don't you use it anymore? There's better alternatives to it?

@danielroe
Copy link
Contributor

danielroe commented Nov 4, 2019

@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. 😃

@MisaelMa
Copy link

MisaelMa commented Nov 10, 2019

@danielroe Do you have any example of the solution?

@danielroe
Copy link
Contributor

danielroe commented Nov 11, 2019

@MisaelMa The solution to what?

@mikinovation
Copy link

mikinovation commented Dec 21, 2019

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...

@mikinovation
Copy link

mikinovation commented Dec 21, 2019

My code is here.

login.vue

import { createComponent, reactive } from '@vue/composition-api'
import { userStore } from '@/store'

....
setup() {
    const state = reactive<State>({
      email: 'mail@sample.com',
      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 }

@jpoep
Copy link

jpoep commented Jan 9, 2020

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:

  1. Clone repo, run yarn && yarn dev
  2. Open localhost:3000
  3. 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?

@woubuc
Copy link

woubuc commented Feb 16, 2020

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.

@jpoep
Copy link

jpoep commented Feb 16, 2020

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.

@akashlama1998
Copy link

akashlama1998 commented Feb 18, 2020

@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"

@danielroe
Copy link
Contributor

danielroe commented Feb 19, 2020

@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.

@akashlama1998
Copy link

akashlama1998 commented Feb 20, 2020

@danielroe Its Ok.. Thanks for the reply.. I already moved my modules to ~/store.

@sniperadmin
Copy link

sniperadmin commented Jul 7, 2020

I have documented some approaches to find out the optimum approach in this ticket: queue-stack/qms-nuxt-ts#17

@puzzle9
Copy link
Contributor

puzzle9 commented Aug 15, 2020

@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

puzzle9 added a commit to puzzle9/vuex-module-decorators that referenced this issue Aug 15, 2020
up readme.md ssr typescript module name (namespaced)

championswimmer#179 (comment)
@ceo-gazprom
Copy link

ceo-gazprom commented Oct 16, 2020

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 {}

@AllanPinheiroDeLima
Copy link

AllanPinheiroDeLima commented Oct 26, 2020

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

@Pacheco95
Copy link

Pacheco95 commented Jan 4, 2021

[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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests