"Encountering a glitch involving Vue.js 3, Pinia, and a centralized store

While using Pinia in a Vue.js 3 project, I encountered an issue. The problem arises when I attempt to load constant JSON structures from my backend using the file src/store/constants.store.ts

// @ts-check
import { defineStore } from "pinia"
import ConstantsApi from "@/api/constants"

export const useConstantsStore = defineStore("constants", {
    state: () => ({
        instanceTiers: [],
        instanceStatuses: [],
        queueStatuses: [],
        countries: [],
        areConstantsLoaded: false,
    }),
    actions: {
        async fetchConstants() {
            this.instanceTiers = await ConstantsApi.instanceTiers();
            this.instanceStatuses = await ConstantsApi.instanceStatuses();
            this.queueStatuses = await ConstantsApi.queueStatuses();
            this.countries = await ConstantsApi.countries();
            this.areConstantsLoaded = true;
        },
    },
})

This code relies on the functions defined in src/api/constants.ts

import {api} from "./api"

export default {
instanceTiers() {
return api("GET", "/instance_tiers");
},
// More API functions...
}

The core function for making API requests is located in src/api/api.ts, where authorization details are stored:

import {APISettings} from './config';
import {useAuthStore} from "@/stores";
import {useNotificationStore} from '@/stores';

const authStore = useAuthStore();

const notificationStore = useNotificationStore();

// Function for handling API requests
export function api(method: string, url: string, data?: any): Promise<any> {
// API request logic here
}

Authorization credentials are stored in src/store/auth.store.ts:

// @ts-check
import { defineStore } from "pinia"

export const useAuthStore = defineStore("auth", {
state: () => ({
token: JSON.parse(localStorage.getItem("token")) as string,
idToken: JSON.parse(localStorage.getItem("idToken-parsed")),
logoutUrl: localStorage.getItem("logout-url") as string,
loginUrl: localStorage.getItem("login-url") as string,
}),
getters: {
getToken: (state) => {
return state.token
},
// More getters...
},
actions: {
logout() {
// Logout action logic here
},
},
})

A central store index file src/stores/index.ts is also present in the project:

export * from "./auth.store";
// More store exports...

import { createPinia } from "pinia";

export const pinia = createPinia();

An error message "Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?" occurs when loading a page.

In my src/main.ts file, I have set up Pinia like this:

import { createApp } from "vue"
import { pinia } from "./stores"
import App from "./App.vue"
import { router } from "./router";
import "./assets/main.css"

const app = createApp(App);
app.use(pinia);
app.use(router);
app.mount("#app");

Changing the content of src/stores/constants.store.ts seems to resolve the issue:

// @ts-check
import { defineStore } from "pinia"

export const useConstantsStore = defineStore("constants", {
state: () => ({
instanceTiers: [],
instanceStatuses: [],
queueStatuses: [],
countries: [],
areConstantsLoaded: false,
}),
actions: {
async fetchConstants() {
this.instanceTiers = [];
this.instanceStatuses = [];
this.queueStatuses = [];
this.countries = [];
this.areConstantsLoaded = true;
},
},
})

Answer №1

Don't forget to initialize Pinia's instance using the createPinia function.

Your code should look something like this:

import { createApp } from "vue"
import { createPinia } from 'pinia'
import App from "./App.vue"
import { router } from "./router"
import "./assets/main.css"

const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(router);
app.mount("#app");

Answer №2

useAuthStore should not be used at the top of a module as it goes against the intended purpose of having a getter function for a store. When utilizing useAuthStore outside of a component, it is recommended to call it where the store is actually being used to avoid premature store instantiation, typically inside api:

import {APISettings} from './config';
import {useAuthStore, useNotificationStore} from '@/stores';

export function api(method: string, url: string): Promise<any>;
export function api(method: string, url: string, data: any): Promise<any>;
export function api(method: string, url: string, data?: any): Promise<any> {
export function api(method: string, url: string, data?: any): Promise<any> {
  const authStore = useAuthStore();
  const notificationStore = useNotificationStore();
  ...

In addition, src/api/constants.ts appears to serve no purpose as an abstraction and this code could be more appropriately placed within store actions.

If src/main.ts does not match the expected structure, it may indicate that Pinia has not been initialized correctly and referencing another answer could also provide clarification.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to retrieve an array of objects that have a property matching another array?

In my array, I have data structured like this: array = [ { name: "john", tag: ["tag1", "tag2"] }, { name: "doe", tag: ["tag2"] }, { name: "jane", tag: ["tag2", "tag3"] } ]; My goal is to create a new array of objects that only contain elements with ...

Utilize CSS to vertically align buttons

One of my current projects involves creating a panel with buttons organized in columns side by side, similar to the layout shown below: However, I am struggling to achieve this desired arrangement. Below is the code I have been working on: <style&g ...

Unable to display socket data in Angular js Table using ng-repeat

div(ng-controller="dashController") nav.navbar.navbar-expand-sm.navbar-dark.fixed-top .container img(src='../images/Dashboard.png', alt='logo', width='180px') ul.navbar-nav li.nav-item ...

Can you please explain the distinction between the statements var a = b = 2 and var a = 2; var b = 2;

Whenever I try to declare a variable within a function, I encounter an issue. var b = 44; function test(){ var a = b = 2; } However, the following code works without any problems: var b = 44; function test(){ var a; var b = 2; } The global ...

Steps to validate individual input text fields that create a date and display an error message if the date is not valid

Currently, I am working on a React Material UI component designed to capture a user's 'Date of Birth'. This component consists of three separate inputs for the day, month, and year. In order to enhance this functionality, I would like to im ...

Employing asynchronous operations and the power of async/await for achieving seamless integration

I am currently facing an issue where I need to retrieve queries from a database stored in Postgres. A function is utilized, which employs a callback mechanism. In order to fetch rows from the database, there exists a function called getRecipesByCategoryFo ...

Looking for assistance with a Vue.js BMI Calculator project

Currently, I am delving into Web Development using Vue. As part of my project, I have constructed a component that calculates the BMI (Body Mass Index) of an individual. To collect the necessary data, I have implemented a form utilizing bootstrap-vue. Howe ...

Scripting events in JavaScript/jQuery are failing to trigger on elements located inside nested <div> containers

I am currently developing a simple RSS reader application where, upon clicking a 'story', the relevant information is displayed in a modal view. The 'stories' or RSS feed items are presented in a scrolling row. However, I have encounte ...

Sending arguments from JavaScript to PHP via ajax

I am facing a challenge where I need to send a JavaScript variable to a PHP function. While I was successful in doing this with hard-coded values, I'm struggling when it comes to using variables. Here's an example of what worked for me: <butt ...

using JavaScript to send numerous text box values to various views

I have a dilemma with passing values between two views. In View1, there are text boxes for entering basic information. After the customer enters this data and clicks on 'add more details', I want to transfer these details to the text boxes in Vie ...

Tips for determining the width of an image and utilizing that measurement as the height in order to create a balanced square image

I am currently facing an issue with my code that is used to retrieve the width of an image which is set in percentages. Although I am able to obtain the width in pixels, I am struggling with correctly inserting the variable into the CSS property value usin ...

Encountering issues with Node.js and Socket.io not displaying results on Internet Explorer when using a secure connection

I have successfully integrated socket.io, node.js, and express to serve real-time json data to multiple browsers except for IE (tested on version 9) over a secure connection. Everything was functioning smoothly until I switched to HTTPS. From the server&ap ...

Troubleshooting a Vue.js issue: How to fix a watch function that stops working after modifying

I have encountered a problem with my code. It seems to be working fine initially after the beforeMount lifecycle hook, but when I try to modify the newDate variable within my methods, it doesn't seem to track the changes. data() { return { ...

The Swiper library is incompatible with the "vue" version "^2.6.11" and cannot be used together

I've been attempting to incorporate Swiper with "vue": "^2.6.11", however I keep encountering runtime errors. Despite following the instructions on , and modifying the imports as advised: // Import Swiper Vue.js components import { ...

What is the best way to implement form fields that have varying validation patterns based on different conditions?

Currently, my focus is on developing a form that prompts the user to choose between "USA" or "International" via radio buttons. The input field for telephone numbers should then adapt its requirements based on the selected country - either a 10-digit US nu ...

Trigger a jQuery click event to open a new tab

On a public view of my site, there is a specific link that can only be accessed by authenticated users. When an anonymous user clicks on this link, they are prompted to log in through a popup modal. To keep track of the clicked link, I store its ID and inc ...

Having trouble extracting a JSON object from a POST request in Express v4 with the help of body-parser?

Currently, I am delving into the world of server-side code and learning about Node.js and Express. However, I am facing some challenges when it comes to receiving and parsing a JSON object sent from a POST request. Despite checking various resources (linke ...

Enhance your <head> section by adding lines when utilizing Layouts within Iron Router

Is there a way to add more lines to the <head> section using Iron Router and layouts? Take for example, inserting the following code snippet into the <head>... <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=ed ...

Submitting a form into a database with the help of AJAX within a looping structure

Trying to input values into the database using AJAX. The rows are generated in a loop from the database, with each row containing a button column. Clicking on the button submits the values to the database successfully. The issue is that it only inserts va ...

Invoke a function within a Vue 3 watch functionality defined within the setup method

Transitioning from Vue 2 to Vue 3 with Quasar has presented a challenge for me regarding watching a value that changes in a store file. In my layout page, I have a select dropdown that modifies the value of my background object in the store: stor ...