I use Vuejs with Vuetify and Vuex and want to create a simple app. Let’s say a very small todo app. For my backend I use an Express REST api and for the HTTP methods I use Axios.
To handle the session I read about two things:
When launching an Axios call I could get an error with the status code 401. I could deal with it using axios.interceptors.response.
instance.interceptors.response.use(res => res, (err) => {
if (err.response.status === 401) {
store.dispatch(‘authentication/destroySession’);
}
return err;
});
When redirecting to another route I could use the beforeRouteEnter event of the vue.js Router and check if the token is valid and not expired.
router.beforeEach((to, from, next) => {
const userIsLoggedIn = checkIfUserIsLoggedIn();
if (!userIsLoggedIn) {
next(false); // stay on this route
} else {
next(); // navigate to the next route
}
});
So far so good. But what happens if one of these approaches have to deal with a “not logged in” state? I don’t want to redirect the user to a login page because then he would loose his current work. And maybe he got no account so he needs to signup first.
If the route or REST endpoint is protected I would cancel the task to execute, show an error alert and after that I would like to render an overlay.
Most resources explain how to redirect to the login page if not logged in but Github for example renders the login page and executes the task after logging in.
How can I render this overlay? Is it even possible? Is there a better approach?
Solution :
Create the overlay HTML (can be in App.vue.js as you mentioned) whose visibility is dependent upon a computed called showOverlay:
<div v-show=”showOverlay”>OVERLAY CONTENT</div>
In the Vuex store, maintain some state which represents the visibility of the overlay:
state.showOverlay = false;
Back in App.vue, map this Vuex state into the showOverlay computed:
import { mapState } from ‘vuex’;
export default {
computed: {
…mapState([‘showOverlay’])
}
}
Wherever you use beforeRouteEnter, or in the router if using beforeEach, import the Vuex store directly (this makes it easy to access the store when this.$store is not accessible):
import store from ‘@/store.js’;
I see you posted example code which uses beforeEach instead of beforeRouteEnter, so use something like:
router.beforeEach((to, from, next) => {
const userIsLoggedIn = checkIfUserIsLoggedIn();
if (!userIsLoggedIn) {
store.state.showOverlay = true;
next(false); // stay on this route
} else {
next(); // navigate to the next route
}
});
After you get this working, it would be best to move the overlay into a component to avoid needlessly editing App.vue. And you’ll need to set the overlay’s state back to false on close.