1
votes

Good day am working on a vue project that uses both vue-router and vuex In the app whenever login is successful, I store the the JWT token in vuex. However im strugling with the following

1) Dynamically show/hide login/logoff buttons in my navbar 2) Access JWT token in vuex store when the routes changes in router.js

So basically i need access to my vuex store in my router and also how to update my navbar component when my vuex state changes (ie when login is successful)

Below is my code. I'll start with main.js

import Vue from 'vue'
import Router from 'vue-router'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import App from '../app.vue'
import router from '../router.js'
import store from '../store'

Vue.use(Router)
Vue.use(Vuetify)

const vuetify = new Vuetify

document.addEventListener('DOMContentLoaded', () => {
  new Vue({
        el: '#app',
        router,
        vuetify,
        store,
        render: h => h(App)         
  })
})

Then router.js

import Router from 'vue-router'
import Index from './views/index.vue'
import Appointments from './views/appointments.vue'
import CreateAppointment from './views/createAppointment.vue'
import Login from './views/login.vue'
import store from './store'

const router =  new Router({
    routes: [
        {
            path: '/',
            name: 'root',
            component: Index
        },
        {
            path: '/login',
            name: 'login',
            component: Login
        },
        {
            path: '/index',
            name: 'index',
            component: Index
        },
        {
            path: '/appointments',
            name: 'appointments',
            component: Appointments,
            props: true,
            meta: { 
                requiresAuth: true
           }
        },
        {
            path: '/create-appointment',
            name: 'create-appointment',
            component: CreateAppointment,
            meta: { 
               requiresAuth: true
           }
        }
    ]
})   

router.beforeEach((to, from, next) => {
  if(to.matched.some(record => record.meta.requiresAuth)) {
    if (store.getters.isLoggedIn) {
      next()
      return
    }    
    next('/login') 
  } else {
    next() 
  }
})

export default router

Then comes store which is index.js inside of store folder

import Vue from 'vue'
import Vuex from 'vuex'
import * as patient from './modules/patient.js'
import * as appointment from './modules/appointment.js'
import * as user from './modules/user.js'
import * as notification from './modules/notification.js'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {},
    modules: {
        user,
        patient,
        appointment,
        notification
    }
})

And lastly is my nabar.vue component which is nested in App.vue. Ps i have taken out navigation drawer and bottom navigation to lessen the code.

<template>
    <nav>       
    <v-app-bar app dark>
        <v-btn text rounded dark v-on:click='showDrawer = !showDrawer'>
            <v-icon class='grey--text' left>menu</v-icon>
        </v-btn>      
      <v-toolbar-title d-sm-none>
        <span class='font-weight-light'>SASSA</span>      
      </v-toolbar-title>
      <v-spacer></v-spacer>   
      <!-- Log in button  -->
      <v-btn text rounded dark v-on:click='login' v-show='!isLoggedIn'>
        <span>Login</span>
        <v-icon class='grey--text' right>arrow_forward</v-icon>
      </v-btn>
      <!-- Log out button  -->
      <v-btn text rounded dark v-on:click='logout' v-show='isLoggedIn'>
        <span>Logout</span>
        <v-icon class='grey--text' right>exit_to_app</v-icon>
      </v-btn>
    </v-app-bar>
    </nav>
</template>

<script>
  import { mapState } from 'vuex'
    export default {
        data(){
            return {
              activeBtn: 1,
              showDrawer: false,
                links: [                    
                    { title: 'Appointments', icon: 'calendar_today', link: '/appointments'},
                    { title: 'New Appointment', icon: 'event', link: '/create-appointment'}
                ]          
            }
        },
    computed: {
      isLoggedIn() {
        var result = (this.$store.getters['isLoggedIn'] == "true")           
        return result
      },      
      ...mapState(['user'])
    },

    methods: {
      logout() {
        this.$store.dispatch('user/logout')
        .then(() => {
          this.$router.push('/login')
        })
      },
      login() {
        this.$router.push('/login')
      }
    }
    }
</script>

This is where i try to access store in router

    if (store.getters.isLoggedIn) {

Any help would be highly appreciated

Below is the user.js module

import AxiosService from '../services/AxiosService.js'

export const namespaced = true

export const state = {
    status: '',             
    token:  '',             
    user:  {}               
}

export const mutations = {
    AUTH_SUCCESS(state, payload){       
        state.status = 'logged_on'
        state.token = payload.token
        state.user = payload.user
    },
    LOGG_OFF(state){
        state.status = 'logged_off'
        state.token = ''
        state.user = {}
    }
}

export const actions = {
    login({commit, dispatch}, user){            
        return AxiosService.logon(user)
        .then(response => {
            const token = response.data.auth_token
            const user = response.data.user             
            localStorage.setItem('token',token)
            commit('AUTH_SUCCESS', {token, user})
        })
        .catch(error => {           
            const notification = {
                type: 'error',
                message: 'Invalid Credentials !!!'
            }   
            dispatch('notification/add', notification, { root: true})
            throw error
        })
    },
    logout({commit}){
        localStorage.setItem('token','')
        commit('LOGG_OFF')
    }
 }

export const getters = {
    isLoggedIn: state => !!state.token,
    authStatus: state => state.status,
    getUser: state => state.user
}
1
What problem do you have with navbar? As for router, possible duplicate of stackoverflow.com/questions/42603909/…Estus Flask
So once someone loggs in, vuex gets updated with a jwt token and i want to hide the login button and display the loggout button.Lyle Phillips
This should happen if you use isLoggedIn in template like you do. Does it not work?Estus Flask
Look like a problem with isLoggedIn. Could you share the module?ellisdod
No it doesnt, it keeps displaying the login button. Because the v-show is supposed to work with computed right ?Lyle Phillips

1 Answers

0
votes

Hey all i managed to fix it.

Problem was because my modules are namepsaced i have to access like this

store.getters['user/isLoggedIn']

Instead of store.user.isLoggedIn

Thanks again. However i still have the issue of the navbar not updating