Search code examples
javascripttypescriptvuejs3vitepinia

use pinia outside of component raises no active pinia error


I'm working on a Vue.js 3 project build using ViteSse template, I wanna use one of my Pinia stores named notificationStore outside of the setup component but I get getActivePinia called with no active Pinia. Did you forget to install Pinia error when I ran the dev command Its behavior is so strange because it does not occur if I add useNotificationStore after the dev server loaded and It works well but when useNotificationStore exists in my ts file and run dev command it raise error.

console error

http-client.ts:

import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import axios from 'axios'
import tokenService from './token.service'
import { useNotificationsStore } from '~/store/notification.store'
const notification = useNotificationsStore()
const httpClient: AxiosInstance
  = axios.create({
    baseURL: `${import.meta.env.VITE_APP_API_URL}/`,
    headers: {
      'Content-Type': 'application/json',
    },
  })


httpClient.interceptors.response.use(
  (response) => {
    if (response.config.method !== 'get') {
      const successMsg = 'operation successfully completed'
      notification.addNotification({ type: 'success', message: successMsg })
    }
    return response
  },
  (error) => {
    if (error.message === 'Network Error') {
      notification.addNotification({ type: 'error', message: 'Network Error' })
      return Promise.reject(error)
    }
    let errorMessage = ''
    const validationErrors = getValidationErrors(error)
    errorMessage = getErrorMessage(error)
    notification.addNotification({ type: 'error', message: errorMessage, validationErrors, hideAfterRouting: false })
  }
)

I have traced the issue with some logging and found that it occurred before createApp was executed that initiated Pinia and there was no active Pinia at that time. I expected createApp in main.ts to have been executed before all

thanks in advance


Solution

  • I managed to solve the problem by reading documentation carefully:

    The easiest way to ensure this is always applied is to defer calls of useStore() by placing them inside functions that will always run after pinia is installed.

    I just update http-client by removing useNotificationStore() from the top of the file and where I need notificaitonStore instance use useNotificationStore().addNotification(...)

    import type { AxiosInstance, AxiosRequestConfig } from 'axios'
    import axios from 'axios'
    import tokenService from './token.service'
    
    const httpClient: AxiosInstance
      = axios.create({
        baseURL: `${import.meta.env.VITE_APP_API_URL}/`,
        headers: {
          'Content-Type': 'application/json',
        },
      })
    
    httpClient.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        const token = tokenService.getLocalAccessToken()
        if (token && config.headers)
          config.headers.Authorization = `Bearer ${token}`
    
        return config
      },
      (error) => {
        return Promise.reject(error)
      },
    )
    httpClient.interceptors.response.use(
      (response) => {
        if (response.config.method !== 'get') {
          const successMsg = 'operation successfully completed'
           useNotificationsStore().addNotification({ type: 'success', message: successMsg })
        }
        return response
      },
      (error) => {
        if (error.message === 'Network Error') {
           useNotificationsStore().addNotification({ type: 'error', message: 'Network Error' })
          return Promise.reject(error)
        }
        let errorMessage = ''
        const validationErrors = getValidationErrors(error)
        errorMessage = getErrorMessage(error)
        useNotificationsStore().addNotification({ type: 'error', message: errorMessage, validationErrors, hideAfterRouting: false })
      }
    )