Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nuxt access store (in Module mode) from JS file

Tags:

I have an AuthService that I use in a namespaced store in my Nuxt app. I need to commit mutations from AuthService to the namespaced store but I can't figure out how to import the store into my AuthService.

I've seen examples where the store is imported into the JS file, but the store is explicitly defined in the Vue app. Because I'm using Nuxt with the Module mode for my store, I'm not sure of the root path where I can import my store into the AuthService file. As I understand it, Nuxt handles creating the root store and all the namespaced store behind the scenes when use "Module mode"

My Nuxt store directory includes index.js (which is empty) and auth.js which has the mutations I want to call from AuthService.

auth.js

import AuthService from '../firebase/authService'

const authService = new AuthService()

export const state = () => ({
  user: null
})

export const mutations = {
  setUser (state, user) {
    state.user = user
  }
}

export const actions = {
  async signUp ({ commit }, payload) {
    try {
      await authServices.createUser(payload)
      return Promise.resolve()
    } catch (err) {
      const notification = {
        duration: 5000,
        message: err.message,
        type: 'error'
      }
      commit('ui/activateNotification', notification, { root: true })
      return Promise.reject()
    }
  }
}

authService.js

import { fAuth, fDb } from './config'

// I think I need to import auth store here but I'm not sure how

export default class AuthClient {
  async createUser (payload) {
    try {
      const res = await fAuth.createUserWithEmailAndPassword(payload.email, payload.password)
      const { uid } = res.user
      const user = {
        ...payload,
        uid
      }
      await this._createUserDoc(user)
      this._initAuthListener()
      return Promise.resolve()
    } catch (err) {
      return Promise.reject(err)
    }
  }

  async _createUserDoc (user) {
    await fDb.collection('users').doc(user.uid).set(user)
  }

  _initAuthListener () {
    fAuth.onAuthStateChanged(async (user) => {
      try {
        if (user) {
          const userProfileRef = fDb.collection('users').doc(user.uid)
          const userProfileDoc = await userProfileRef.get()
          const { uid, userName } = userProfileDoc.data()

          // Here is where I want to call a mutation from the auth store

          this.store.commit('setUser', {
            uid,
            userName
          })
        } else {
          this.store.commit('setUser', null)
        }
      } catch (err) {
        console.log(err)
      }
    })
  }
}

like image 462
Nic Stelter Avatar asked Feb 14 '20 01:02

Nic Stelter


People also ask

How does Nuxt store work?

If the action nuxtServerInit is defined in the store and the mode is universal , Nuxt will call it with the context (only from the server-side). It's useful when we have some data on the server we want to give directly to the client-side. Only the primary module (in store/index. js ) will receive this action.

Can I use Vuex in Nuxt?

Conclusion. Working with Vuex in a Nuxt application is simple and easy to get started with. It provides module creation based on folder and file structure under the store folder.

What is nuxtServerInit?

nuxtServerInit: it is used to fetch some data you work with a lot (such as userInfo in the session), only once, then you can use it in all the components. So, you don't have to constantly reach out to the server. Moreover, it is an action in the store provided by Vuex, so it'll dispatch automatically by Vuex.


1 Answers

I'd like to propose a solution using a plugin.

In the external module (externalModule.js) we define store variable and export an init function that receives Nuxt context as argument. The function assignes the store from context to the variable which can be now used in the module:

let store;
export function init (context) {
    store = context.store;
};
(...further business logic using store)

Then in the plugins folder we create a plugin file (let's call it storeInit.js). The file imports the init function from the external module and exports default plugin function required by Nuxt. The function receives context from Nuxt and we call the init function passing the context further:

import { init } from '[pathTo]/externalModule.js';
export default (context, inject) => {
    init(context);
};

Then we register the plugin in the nuxt.config.js file:

module.exports = {
    ...
    plugins: [
        { src: '~/plugins/storeInit' }
    ],
    ...
}

This way when the app is built by Nuxt and plugins are registered, the context object is passed to the external module and we can use anything from it, among others the store.

like image 62
Eggon Avatar answered Oct 05 '22 18:10

Eggon