Home > Mobile >  Vue 3 Composition Api , Vue-router 4 Naigation guards throw an Error when using it
Vue 3 Composition Api , Vue-router 4 Naigation guards throw an Error when using it

Time:01-09

When I try to use navigation guard from Vue-router 4, my code is no longer working it show a errors with undefined (push) from Pinia store router.push('/'). Here is my code:

import { createRouter, createWebHistory } from "vue-router";
import manageStaffRoutes from "./manage.staff.js";
import authRoutes from "./login.js";

import { useAuthStore } from "@/stores/auth.store.js";

const routes = [...manageStaffRoutes, ...authRoutes];

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
});

router.beforeEach(async (to, from) => {
    const auth = await useAuthStore();
    const publicPages = ["/login", "/super-admin-login"];
    const authRequired = !publicPages.includes(to.path);
    if (authRequired && !auth.user) {
        return "/";
    }
});
export default router;

then in my store I have this code , where I am trying to redirect the user after successfully login

import { defineStore } from "pinia";
import { ref, computed } from "vue";
import axios from "axios";
import { useRouter } from "vue-router";

export const useAuthStore = defineStore("userAuth", () => {
    const router = useRouter();
    const userData = ref(null);
    const errorMessages = ref(null);

    const user = computed(() => {
        return JSON.parse(localStorage.getItem("user"));
    });

    if (user.value) {
        axios.defaults.headers.common["Authorization"] = `${user.value.token}`;
    }

    async function login(email, password) {
        try {
            const data = await axios.post("api/v1/users/login", {
                email: email,
                password: password,
            });
            if (data.status === 200) {
                userData.value = data.data;
                localStorage.setItem(
                    "user",
                    JSON.stringify(userData.value.data)
                );
                await router.push("/"); // the error
               
            }
        } catch (error) {
            console.log(error);
            return (errorMessages.value = error.response.data.errorsToSend);
        }
    }

    const logout = async () => {
        try {
            const data = await axios.post("api/v1/users/logout");
            console.log(data);
            if (data.status === 201) {
                user.value = null;
                localStorage.removeItem("user");
                await router.push({ name: "login" }); // the error
            
            }
        } catch (error) {
            console.log(error);
            // return (errorMessages.value = error.response.data.message);
        }
    };
    return { login, user, errorMessages, logout };
});

Here is the error: enter image description here

CodePudding user response:

Following the single responsability principle I suggest you to change the login() function on the store, remove the router push to let the store only authenticate your user. By doing this the redirection is handled by the calling funcion an not by the login.

AuthStore

import { defineStore } from "pinia";
import { ref, computed } from "vue";
import axios from "axios";

export const useAuthStore = defineStore("userAuth", () => {

    // .... 

    async function login(email, password) {
        try {
            const data = await axios.post("api/v1/users/login", {
                email: email,
                password: password,
            });

            if (data.status === 200) {
                userData.value = data.data;
                localStorage.setItem(
                    "user",
                    JSON.stringify(userData.value.data)
                );
            }
        } catch (error) {
            console.log(error);
            return (errorMessages.value = error.response.data.errorsToSend);
        }
    }
};

Router

import { useAuthStore } from "@/stores/auth.store.js";

// ...

router.beforeEach(async (to, from) => {
    const authStore = useAuthStore();
    const publicPages = ["/login", "/super-admin-login"];
    const authRequired = !publicPages.includes(to.path);

    if (authRequired && !auth.user) {
        return "/";
    }
});
  • Related