How to store user info after login in Vuex - vue.js

I am trying to make an api call in login and I want to store it in Vuex store. So in the beginning my mutation:
export const STORE_USER = (state, {user}) => {
state.user = user;
}
and my action:
export const storeUser = ({commit}, {user}) => {
commit('STORE_USER', {user});
}
So as you see after login, I want to make an api call and get the user information. I want to this user information in Vuex store but it comes empty.
So I am expecting the state that you see above should be filled after login. My login component is:
export default {
name: 'Login',
mounted() {
EventBus.$on(GENERAL_APP_CONSTANTS.Events.CheckAuthentication, () => {
this.authenticated = authHelper.validAuthentication();
this.cookie = cookieHelper.getCookie(this.cookieName);
this.cookieValue = cookieHelper.getCookieValue(this.cookie);
if (this.authenticated) {
this.email = this.password = "";
this.authenticationFailed = false;
this.storeUser();
}
});
EventBus.$on(GENERAL_APP_CONSTANTS.Events.LoginFailed, () => {
this.authenticationFailed = true
});
},
data () {
return {
authenticated: false,
authenticationFailed: false,
email: '',
password: '',
rememberMe: false,
cookieName: "_token",
cookie: "",
cookieValue: "",
}
},
methods: {
signIn: function () {
authHelper.signIn(this.email, this.password, () => {
this.$router.push({name: 'home'});
});
},
storeUser: function () {
apiHelper.getRequest(
`/users/${cookieHelper.parseJwt(this.cookieValue).user_id}`,
(response) => {
this.$store.dispatch('storeUser', {
user: response.data,
})
}
)
},
}
}
So why do you think the in-store user Object is empty? Because I response.data is not empty either. Please let me know.

Related

Unable to store data in vuex "State"

I am unable to store the data from the API in the state, is there any issue in my code?
I am not able to console.log(state.token) or state.token from the mutations.
My Store
export const AUTH_MUTATIONS = {
SET_USER: 'SET_USER',
SET_PAYLOAD: 'SET_PAYLOAD',
LOGOUT: 'LOGOUT',
}
export const state = () => ({
token: null,
userdata: [],
data: [],
})
export const mutations = {
[AUTH_MUTATIONS.SET_USER] (state, { userdata }) {
state.userdata = userdata
},
[AUTH_MUTATIONS.SET_PAYLOAD] (state, { token }) {
state.token = token
},
}
export const actions = {
async login ({ commit, dispatch }, { email_id, password }) {
const { data: {data: { user, token } } } = await this.$axios.post('http://18.xxx.246.xxx:5000/api/v1/users/login',
{
email_id,
password
})
// console.log(user)
// console.log(token)
commit(AUTH_MUTATIONS.SET_USER, user)
commit(AUTH_MUTATIONS.SET_PAYLOAD, token)
// console.log(AUTH_MUTATIONS.SET_USER, user)
},
}
export const getters = {
isAuthenticated: (state) => {
return state.token && state.token !== ''
},
}
In your action you need to take in state in the destructured parameters like this: { commit, dispatch, state } then you will be able to access your state and log state.token.
If it's still null after that point then you should debug it to ensure that you're setting it correctly in the mutation itself.

how solve Avoided redundant navigation to current location: "/login". in vue?

Hi everybody i'm trying to make login page and redirect to home page ('/')
When i'm logging i haven't errors in console i can see the error using vue devtools
ERROR VUE DEV TOOL
End of navigation
/login
02:27:19.124
guard:afterEach
failure:Avoided redundant navigation to current location: "/login".
status:❌
from:/login
fullPath:"/login"
path:"/login"
query:Object (empty)
hash:""
name:"login"
params:Object (empty)
matched:Array[1]
meta:Object (empty)
redirectedFrom:undefined
href:"/login"
to:/login
fullPath:"/login"
hash:""
query:Object (empty)
name:"login"
path:"/login"
params:Object (empty)
matched:Array[1]
meta:Object (empty)
redirectedFrom:Object
href:"/login"
this is my login's method
methods:{
async submitForm(user){
const userForm=new FormData();
userForm.append("username", this.username);
userForm.append("password", this.password);
await this.$store.dispatch("auth/login", userForm).then(
()=>{
const user = localStorage.getItem('user')
console.log(user) //to check if i logged, in console get undefined but if try localStorage.getItem('user') i got the user.
this.$router.push('/')
}),
(error)=>{
console.log(error)
}
}
}
ROUTES
const router = createRouter({
history: createWebHistory(),
scrollBehavior() {
return { top: 0 }
},
routes,
})
{
path: '/',
name: 'dashboard',
component: () => import('#/views/Dashboard.vue'),
children: [
{
path: '',
name: 'home',
component: () => import('#/views/dashboard/Home.vue'),
},
....
router.beforeEach((to, from, next) => {
const publicPages = ['/login'];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
// trying to access a restricted page + not logged in
// redirect to login page
if (authRequired && !loggedIn) {
next('/login');
} else {
next();
}
});
auth.service
class AuthService {
login(user) {
let dator={
access_token: '',
user:{}
}
console.log('AUTHSERVICE-->\n'+user)
return axios
.post(API_URL + 'login/access-token', user)
.then(response => {
console.log(response.data.access_token)
if (response.data.access_token) {
dator.access_token=response.data.access_token
localStorage.setItem('token', JSON.stringify(dator.access_token))
axios.get(API_URL + 'users/me/', { headers: authHeader() })
.then(response =>{
localStorage.setItem('user', JSON.stringify(response.data))
dator.user=response.data
})
}
return dator;
});
}
auth.module VUEX
import AuthService from '../services/auth.service';
const token = JSON.parse(localStorage.getItem('token'));
const user = JSON.parse(localStorage.getItem('user'));
const initialState = token && user
? { status: { loggedIn: true }, token,user }
: { status: { loggedIn: false }, token:null, user: null };
export const auth = {
namespaced: true,
state: initialState,
actions: {
login({ commit }, userForm) {
console.log(userForm)
return AuthService.login(userForm).then(
datologin => {
console.log('datologin',datologin)
commit('loginSuccess', datologin);
return Promise.resolve(datologin);
},
error => {
commit('loginFailure');
return Promise.reject(error);
}
);
},
if after login i force the '/' in the browser the page work. So i don't know where is my bad.
Sorry for noob error. The problem was in second request with axios so i refactor this part and now work
async asyncLogin(user){
let uservuex={
access_token: '',
user:{}
}
try{
const token = await axios.post(API_URL + 'login/access-token', user)
uservuex.access_token = await token.data.access_token
localStorage.setItem('token', JSON.stringify(uservuex.access_token))
const me = await axios.get(API_URL + 'users/me/', { headers: authHeader() })
uservuex.user= await me.data
localStorage.setItem('user', JSON.stringify(uservuex.user))
}catch(error){
console.log(error)
}
return uservuex
}

Store user in vuex after login

I am trying to create login page. SO for this, I am making a call. After I get the response, I am storing cookie and with the cookie I am getting the user info. What I am trying to do is store this user info in Vuex store. Here is whole of my logic for this:
export default {
name: 'Login',
mounted() {
EventBus.$on(GENERAL_APP_CONSTANTS.Events.CheckAuthentication, () => {
this.authenticated = authHelper.validAuthentication();
if (this.authenticated) {
this.email = this.password = "";
this.authenticationFailed = false;
}
});
EventBus.$on(GENERAL_APP_CONSTANTS.Events.LoginFailed, () => {
this.authenticationFailed = true
});
},
data () {
return {
authenticated: false,
authenticationFailed: false,
email: '',
password: '',
rememberMe: false,
cookieName: "_token",
cookie: "",
cookieValue: "",
}
},
validations: {
email: {
required,
email,
},
password: {
required,
minLength: minLength(0)
},
},
methods: {
signIn: function () {
authHelper.signIn(this.email, this.password, () => {
this.$router.push({name: 'home'});
});
this.cookie = cookieHelper.getCookie(this.cookieName);
this.cookieValue = cookieHelper.getCookieValue(this.cookie);
this.storeUser();
},
storeUser: function () {
apiHelper.getRequest(
`/users/${cookieHelper.parseJwt(this.cookie).user_id}`,
(response) => {
this.$store.dispatch('storeUser', {
user: response.data,
})
}
)
},
}
}
So, as you see below, my user in Vuex store is still empty:
my mutation is:
export const STORE_USER = (state, {user}) => {
state.user = user;
}
my action is:
export const storeUser = ({commit}, {user}) => {
commit('STORE_USER', {user});
}
Could you have a look and let me know, where do you think I am making something wrong.

Unknown action type in Nuxt Vuex store

I have a problem calling the action from vuex. Everytime I try to access the loginUser action I get an error 'unknown action type' from vuex. maybe I'm not calling it the right way. Please tell me what's wrong with my code.
store: user.js
import axios from 'axios'
export const state = () => ({
users: [],
loggedIn: false,
})
export const getters = {
getLoggedIn: (state) => { return state.loggedIn },
}
export const actions = {
loginUser({ commit }, payload){
if(state.loggedIn){
console.log("you're already logged in!")
}else{
return new Promise(async(resolve, reject) => {
const { data } = await axios.post('/api/users/login-admin', {
login: payload.login,
password: payload.password
})
if(data.success){
commit("loggedIn", true)
resolve()
}else{
commit("loggedIn", false)
reject('an error has ocurred')
}
return data.success
}).catch(err => alert(errCodes(err.code)))
}
},
}
export const mutations = {
setLoggedIn(state, payload) {
state.loggedIn = payload
}
}
login.vue
computed: {
...mapGetters(['getCount'] , {user: 'getLoggedIn'}),
...mapActions([
'loginUser'
]),
},
methods: {
onSubmit: function(){
this.$store.dispatch({
type: 'loginUser',
email: this.login,
pass: this.pass
}).then(()=>{
this.$router.push('../admin_2065')
this.onReset()
}).catch(e => console.log(e))
},
onReset(){
this.login = ''
this.pass = ''
this.$nextTick().then(() => {
this.ready = true
})
}
},
error:
any help will be appreciated, thanks.
mapActions should be inside the methods option and add the namespace user/ :
computed: {
...mapGetters(['getCount'] , {user: 'getLoggedIn'}),
},
methods: {
...mapActions([
'user/loginUser'
]),
onSubmit: function(){
this['user/loginUser']({
email: this.login,
pass: this.pass
}).then(()=>{
this.$router.push('../admin_2065')
this.onReset()
}).catch(e => console.log(e))
},
onReset(){
this.login = ''
this.pass = ''
this.$nextTick().then(() => {
this.ready = true
})
}
},

Access Vue app (this) from non vue file

I'm new to vue (started using vue 2) I'm using Store (vuex) and I'm trying to acheive something.
basically I managed to install the vue-auth plugin : I have this.$auth that I can call from within .vue files.
Now using the store I wanna call the userLogin function by dispatching the call like this from a vue file :
<script>
export default {
computed: {
comparePasswords() {
return this.password === this.passwordConfirm
? true
: "Passwords don't match";
}
},
methods: {
userSignUp() {
if (this.comparePasswords !== true) {
return;
}
this.$store.dispatch("userSignUp", {
email: this.email,
password: this.password
});
}
},
data() {
return {
email: "",
password: "",
passwordConfirm: ""
};
}
};
</script>
in the store/index I'm trying to access the 'this.$auth' I do understand is some kind of context switching but I don't know how to access the vue app instance. :
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let app = this
export const store = new Vuex.Store({
state: {
appTitle: 'LiveScale Dashboard',
user: null,
error: null,
loading: false
},
mutations: {
setUser(state, payload) {
state.user = payload
},
setError(state, payload) {
state.error = payload
},
setLoading(state, payload) {
state.loading = payload
}
},
actions: {
userLogin({ commit }, payload) {
commit('setLoading', true)
var redirect = this.$auth.redirect(); // THIS IS WRONG.
this.$auth.login({ // THIS IS WRONG.
body: payload, // Vue-resource
data: payload, // Axios
rememberMe: this.data.rememberMe,
redirect: { name: redirect ? redirect.from.name : 'account' },
fetchUser: this.data.fetchUser
})
.then(() => {
commit('setUser', this.context)
commit('setLoading', false)
router.push('/home')
}, (res) => {
console.log('error ' + this.context);
commit('setError', res.data)
commit('setLoading', false)
});
},
userSignUp({ commit }, payload) {
// ...
}
},
getters: {}
})
Thanks for your help
try using Vue.$auth in index.js it should work
The idea (so far) is to pass the instance as an argument to the function as follows :
this.$store.dispatch("userSignUp", {
email: this.email,
password: this.password,
auth: this.$auth //added this line
});
and then in the store -> actions , payload.auth will contain my auth plugin :
userLogin({ commit }, payload) {
commit('setLoading', true)
var redirect = payload.auth.redirect();
payload.auth.login({
body: payload, // Vue-resource
data: payload, // Axios
rememberMe: this.data.rememberMe,
redirect: { name: redirect ? redirect.from.name : 'account' },
fetchUser: this.data.fetchUser
})
.then(() => {
commit('setUser', this.context)
commit('setLoading', false)
router.push('/home')
}, (res) => {
console.log('error ' + this.context);
commit('setError', res.data)
commit('setLoading', false)
});
},
I don't know if it's the best practice or not, but this is how I managed to do it. Please feel free to suggest anything.