Mohammadreza Ahmadpour
Mohammadreza Ahmadpour

Reputation: 111

The localStorage is not refreshing in Vuex

I write codes with Vuex to login and logout in my Laravel single page application it's working well but when i login to an account the profiles information (name, address, Email, ...)doesn't show in profile but after i reload the page the profile information loads, and when another user try the profile the data of the last person that login shown to him/her

auth.js:

export function registerUser(credentials){
    return new Promise((res,rej)=>{
        axios.post('./api/auth/register', credentials)
        .then(response => {
            res(response.data);
        })
        .catch(err => {
            rej('Somthing is wrong!!')
        })
    })
}

export function login(credentials){
    return new Promise((res,rej)=>{
        axios.post('./api/auth/login', credentials)
        .then(response => {
            res(response.data);
        })
        .catch(err => {
            rej('The Email or password is incorrect!')
        })
    })
}

export function getLoggedinUser(){
    const userStr = localStorage.getItem('user');

    if(!userStr){
        return null
    }

    return JSON.parse(userStr);
}

store.js:

import {getLoggedinUser} from './partials/auth';
const user = getLoggedinUser();
export default {
    state: {
        currentUser: user,
        isLoggedIn: !!user,
        loading: false,
        auth_error: null,
        reg_error:null,
        registeredUser: null,
    },
    getters: {
        isLoading(state){
            return state.loading;
        },
        isLoggedin(state){
            return state.isLoggedin;
        },
        currentUser(state){
            return state.currentUser;
        },
        authError(state){
            return state.auth_error;
        },
        regError(state){
            return state.reg_error; 
        },
        registeredUser(state){
            return state.registeredUser; 
        },

    },
    mutations: {
        login(state){
            state.loading = true;
            state.auth_error = null;
        },
        loginSuccess(state, payload){
            state.auth_error = null;
            state.isLoggedin = true;
            state.loading = false;
            state.currentUser = Object.assign({}, payload.user, {token: payload.access_token});

            localStorage.setItem("user", JSON.stringify(state.currentUser));
        },
        loginFailed(state, payload){
            state.loading = false; 
            state.auth_error = payload.error;
        },
        logout(state){
            localStorage.removeItem("user");
            state.isLoggedin = false;
            state.currentUser = null;
        },
        registerSuccess(state, payload){
            state.reg_error = null;
            state.registeredUser = payload.user;
        },
        registerFailed(state, payload){
            state.reg_error = payload.error;
        },
    },
    actions: {
        login(context){
            context.commit("login");
        },
    }
};

general.js:

export function initialize(store, router) {
    router.beforeEach((to, from, next) => {
        const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
        const currentUser = store.state.currentUser;

        if(requiresAuth && !currentUser) {
            next('/login');
        } else if(to.path == '/login' && currentUser) {
            next('/');
        } else {
            next();
        }

        if(to.path == '/register' && currentUser) {
            next('/');
        }

    });

    axios.interceptors.response.use(null, (error) => {
        if (error.resposne.status == 401) {
            store.commit('logout');
            router.push('/login');
        }

        return Promise.reject(error);
    });

    if (store.getters.currentUser) {
        setAuthorization(store.getters.currentUser.token);
    }
}

export function setAuthorization(token) {
    axios.defaults.headers.common["Authorization"] = `Bearer ${token}`
}

I think that this issue is relate to my localstorage, how can i fix this? I'm novice at the Vue and don't have any idea what is the problem.

Login Component:

<template>
<main>
    <form @submit.prevent="authenticate">
    <div class="grid-x grid-padding-x">

        <div class="small-10 small-offset-2 cell" v-if="registeredUser">
            <p class="alert success">Welcome {{registeredUser.name}}</p>
        </div>
        <div class="small-10 small-offset-2 cell" v-if="authError">
            <p class="alert error">
                {{authError}}
            </p>
        </div>

        <div class="small-2 cell">
            <label for="email" class="text-right middle">Email:</label>
        </div>
        <div class="small-10 cell">
             <input type="email" v-model="formLogin.email" placeholder="Email address">
        </div>


        <div class="small-2 cell">
            <label for="password" class="text-right middle">Password:</label>
        </div>
        <div class="small-10 cell">
             <input type="password" v-model="formLogin.password" placeholder="Enter password">
        </div>

        <div class="small-10 small-offset-2 cell">
            <div class="gap"></div>
            <input type="submit" value="Login" class="button success expanded">
        </div>
    </div>

    </form>

</main>

</template>

<script>
import {login} from '../../partials/auth';
export default {
    data(){
        return {
            formLogin: {
            email: '',
            password: ''
        },
        error: null
        }
    },
    methods:{
        authenticate(){
            this.$store.dispatch('login');

        login(this.$data.formLogin)
            .then(res => {
                this.$store.commit("loginSuccess", res);
                this.$router.push({path: '/profile'});
            })
            .catch(error => {
                this.$store.commit("loginFailed", {error});
            })
        }
    },
    computed:{
        authError(){
            return this.$store.getters.authError
        },
        registeredUser(){
            return this.$store.getters.registeredUser
        }
    }
}
</script>

Upvotes: 0

Views: 2668

Answers (2)

Mohammadreza Ahmadpour
Mohammadreza Ahmadpour

Reputation: 111

I solved the problem.I have this code in my EditProfile component.

methods: {
            getAuthUser () {
                axios.get(`./api/auth/me`)
                .then(response => {
                    this.user = response.data
                })
            },
}

this.user = response.data is wrong, I changed to this:

getAuthUser () {
    this.user = this.$store.getters.currentUser
},

Upvotes: 0

memic84
memic84

Reputation: 129

Localstorage data is once loaded on page load, so when you use setItem, this won't be visible until the next time.

You should store the data to vuex store, and use that as the source. Only set and get the data from localstorage on page loads.

Otherwise use something like: https://github.com/robinvdvleuten/vuex-persistedstate

Upvotes: 2

Related Questions