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 };
});
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 "/";
}
});