Vue accessing Vuex store in router file - vue.js

I am trying to access my store in the router file as follow, but it's not working. Giving me undefined when I console. Any advice? I am using Vue 3. Thank you in advance!
import store from '../store/index'
const preventRoutes = {
beforeEach: (to, from, next) => {
console.log(store.getters.getLoginState);
if (store.getters.getLoginState === "true") {
console.log("i reached if")
next();
} else {
console.log("i reached else")
next("/");
}
}
}

maybe is because the before route load before the imports
try to import it directly from the before route:
router.beforeEach(function (...) {
const store = require('./store')
store.blah...
})

I have similar situation.
import store from "../store"; to router
then I can use store's API (commit etc ) inside router.beforeEach

Related

How can I use router in store for Quasar

I'm trying to redirect to dashboard after login.
I found this in app.js file that
// make router instance available in store store.$router = router
So I codede that in my login method of auth.js file like below.
store.$router.push({ name: 'dashboard' })
But there is nothing to happen.
How can I use router in vuex store file?
Router is not available in the store directly. You might have to use plugin which makes the router available to the store.
Here is the Vuex-Router plugin which helps to access router to the store.
Are you trying to call router.push in an vuex action?
If so i am doing the same in my quasar v2 project
store/auth/actions.js
import { api } from 'boot/axios'
export function login({ dispatch, commit }, data) {
return api.post('/user/login', data).then(res => {
commit('setToken', res.data.token)
this.$router.push({ name: 'dashboard' }) // <-- What you are looking for?
}).catch(err => {
let msg = err.response.data || 'Error occurred'
return Promise.reject(msg)
})
}

Access Nuxt Router in plugin

I've created a Nuxt plugin that is loaded in the config file with some global functions. In one function, I'd like to access the router, and push to a new route. I am getting an error that router is undefined. Can someone help me understand how I access the router here, if its not attached to the context.
export default (context, inject) => {
const someFunction = () => {
context.router.push({ name: 'route-name' } })
}
}
Try to destruct the context then use app to access the router :
export default ({app}, inject) => {
const someFunction = () => {
app.router.push({ name: 'route-name' } })
}
}
I figured this out. When using context, you can access the router, like this:
context.app.router

Vuejs - Can I use an imported function in my global router.beforeEach

I am trying to use an imported function in my global router guard. But I'm getting this error:
getCurrentStage is not defined
getCurrentStage is imported from shops.js
shop.js looks like this
import axios from 'axios'
export function getCurrentStage() {
axios.get("/admin/wine_app/shops").then(response => {
return response.data.current_stage;
});
}
export default getCurrentStage
I then import it like this: import getCurrentStage from '../api/shops'
And then try and use it like this in my global router guard:
router.beforeEach((to, from, next) => {
if(to.name == null){
let current_stage = getCurrentStage();
}
else {
next();
}
})
But I get the not defined error. Any help?
You haven't returned anything in the exported function. You need to return the axios promise so that current_stage has something returned to it:
export function getCurrentStage() {
return axios.get("/admin/wine_app/shops").then(response => {
return response.data.current_stage;
});
}
That's just going to return the promise so you'll need to do some appropriate async stuff like await or .then with that promise. For example:
getCurrentStage().then(stage => {
current_stage = stage;
});
You're also exporting the function twice which is probably not intentional. You don't need the first export if you only plan to retrieve it by importing the default.

How to test vue router beforeRouteUpdate navigation guard?

First off, I'm using Vue-property-decorator.
My component has a component route, defined like this.
#Component({
components: {
ComponentA,
ComponentB
},
beforeRouteUpdate (to, _from, next) {
const { checkInDate, checkOutDate, items, currency, locale } = to.query;
const queryFullfilled = !!checkInDate && !!checkOutDate && !!items.length && !!currency && !!locale;
if ([BOOKING_PAGE, RESERVATION_PAGE].indexOf(to.name) > -1 && queryFullfilled) {
this.validateRooms();
}
next();
}
})
export default class Layout extends Vue {}
What do I need to do in my specs in order to cover what goes on in beforeRouteUpdate? I've googled this and people are pointing calling wrapper.vm.$options.beforeRouteUpdate.call()... that didn't work for me.
Has anyone done this before? Any code samples I can look at?
Thanks in advance.
John.
If anyone still looking for an answer following code will work.
const beforeRouteUpdate = wrapper.vm.$options.beforeRouteUpdate[0];
let nextFun = jest.fn();
// in place wrapper.vm you can send any object you want bcz when we call beforeRouteUpdate it looses this context
beforeRouteUpdate.call(wrapper.vm , "toObj", "fromObj", nextFun);
how to call beforeRouteUpdate github
import component from '#/components/component'
const wrapper = shallowMount()
// any additional setup
const to = {}
const from = {}
const next = jest.fn()
await component.beforeRouteLeave.call(wrapper.vm, to, from, next)
// asserts
expect(next).toHaveBeenCalledWith(false)
The route guard can be accessed through the component class. Pass in the vm of the instance so you have access to this .

vuex persisted state not working with vue router navigation guard

I've added vuex-persistedstate as defined in documentation. (confirmed and working)
export default new Vuex.Store({
modules: {
auth,
},
plugins: [VuexPersistedState()]
});
I've set up a router navigation guard to redirect to home page on login
/* Auth based route handler */
router.beforeEach((to, from, next) => {
if (to.meta.hasOwnProperty('requiresAuth')) {
if (to.meta.requiresAuth === true) {
let isAuthenticated = authStore.getters.isAuthenticated
if (isAuthenticated(authStore.state) === true) {
next()
} else {
next({name: 'login'})
}
} else {
let isAuthenticated = authStore.getters.isAuthenticated
console.log(authStore.state)
if (isAuthenticated(authStore.state) === true) {
next({name: 'home'})
} else {
next()
}
}
} else {
next()
}
})
The vuex persistedstate restores store from local storage but not before navigation guard!
I can provide any necessary part of the source code for evaluation. Please comment your request as needed. Experimental solutions are also welcome. This is just a personal training application for me!
Help is appreciated!
I know this is probably of no use to #Vaishnav, but as I wen't down the same rabbit hole recently I figured I'd post a workaround I found for this here as this was the only post I found that asked this issue specifically.
in your store/index.js You need to export both the function and the store object.
Change this :
export default() => {
return new vuex.Store({
namespaced: true,
strict: debug,
modules: {
someMod
},
plugins: [createPersistedState(persistedStateConfig)]
});
};
to:
const storeObj = new vuex.Store({
namespaced: true,
strict: debug,
modules: {
someMod
},
plugins: [createPersistedState(persistedStateConfig)]
});
const store = () => {
return storeObj;
};
export {store, storeObj}
Then also, as you have now changed the way you export the store you will also need to change the way it's imported.
Everywhere in your app you've imported the store ie: in main.js -> import store from '#/store' excluding the router.js you will need to change to import {store} from '#/store'
And in your router.js just import {storeObj} from '#/store' and use that instead of store in your router guard ie: storeObj.getters['someMod/someValue']
I found a working example.
As the router isn't a component.
In router config file -
import authStore from '#/stores/auth/store'
Instead -
import store from '#/store'
in navigation guard, I replaced
let isAuthenticated = authStore.getters.isAuthenticated
if(isAuthenticated(authstore.state) === true){...}
with -
let isAuthenticated = store.getters['auth/isAuthenticated']
if(isAuthenticated === true){...}
And now this works like charm...