vuex-module-decorators icon indicating copy to clipboard operation
vuex-module-decorators copied to clipboard

How to use with nuxtServerInit

Open felixoi opened this issue 4 years ago • 2 comments

Hey, I'm using nuxt-property-decorator which just exports some stuff of this module. So I'm reporting it here, because i think it's not a question for the nuxt-property-decorator module. I've created this module (store/usermodule.ts):

import {
  Module,
  VuexAction,
  VuexModule,
  VuexMutation,
} from 'nuxt-property-decorator'
import type { Context } from '@nuxt/types'
import type { User } from '~/types/ore/user'

@Module({
  name: 'usermodule',
  stateFactory: true,
  namespaced: true,
})
export default class UserModule extends VuexModule {
  user: User | undefined = undefined

  @VuexMutation
  setUser(user: User) {
    this.user = user
  }

  @VuexAction({ commit: 'setUser', rawError: true })
  init({ $axios }: Context) {
    $axios.$get<User>('/api/users/@me').then((u: User) => {
      return u
    })
  }
}

And i want to call the init action on nuxtServerInit so i created this store/index.ts

import type { Store, ActionTree } from 'vuex'
import { initializeStores } from '~/utils/store-accessor'

const initializer = (store: Store<any>) => initializeStores(store)
export const plugins = [initializer]
export const actions: ActionTree<any, any> = {
  async nuxtServerInit({ dispatch }, { $axios }) {
    await dispatch('usermodule/init', { $axios })
  },
}

export * from '~/utils/store-accessor'

store-accessor:

import { Store } from 'vuex'
import { getModule } from 'nuxt-property-decorator'
import UserModule from '~/store/usermodule'

// eslint-disable-next-line import/no-mutable-exports
let userStore: UserModule

function initializeStores(store: Store<any>): void {
  userStore = getModule(UserModule, store)
}

export { initializeStores, userStore }

When doing so I'm running into the following error:

ERR_STORE_NOT_PROVIDED: To use getModule(), either the module should be decorated with store in decorator, i.e. @Module({store: store}) or store should be passed when calling getModule(), i.e. getModule(MyModule, this.$store)

Without the dispatch to the usermodule everything is working fine. Whats the correct way of doing this?

felixoi avatar Jul 31 '20 12:07 felixoi

i am also facing this problem

binoysarker avatar Mar 10 '21 10:03 binoysarker

Avoiding the duplicating, I'll post my instance here.


I am sorry for the question in issues. Before open this issue, I asked same question in StackOverflow and even did the contest. The only one answer does not contain the working solution.


According this answer on Stack overflow, below listing from the vuex-module-decorators official documentation

// @/store/index.ts
import Vuex from 'vuex'

const store = new Vuex.Store({
  /*
  Ideally if all your modules are dynamic
  then your store is registered initially
  as a completely empty object
  */
})

in the Nuxt case must be:

import Vue from "vue";
import Vuex, { Store } from "vuex";


Vue.use(Vuex);

export const store: Store<unknown> = new Vuex.Store<unknown>({});

But how to integrate the nuxtServerInit action is above methodology? In below listing of store/index.ts, the nuxtServerInit will not be called.

import Vue from "vue";
import Vuex, { Store } from "vuex";


Vue.use(Vuex);

export const store: Store<unknown> = new Vuex.Store<unknown>({
  actions: {
    nuxtServerInit(context: unknown): void {
      console.log("Called !");
      console.log(context);
    }
  }
});

Update

The David Bernal's solution works, but with warning:

WARN  Classic mode for store/ is deprecated and will be removed in Nuxt 3. 
import Vuex, { Store } from "vuex";

interface RootState {}
export const store = new Vuex.Store<RootState>({
  actions: {
    nuxtServerInit: () => {
      console.log("Hello nuxtServerInit");
    }
  }
});

const createStore = (): Store<RootState> => {
  return store;
};

export default createStore;

TokugawaTakeshi avatar Oct 14 '21 07:10 TokugawaTakeshi