I keep trying to get my action to set data so i can pull it from a getter and for some reason it doesnt seem to be working. The data from the getter is always blank. I have the argument payload which matches the case on my switch statement and matches the object in my initialstate. I keep getting a Cannot set properties of undefined (setting 'GOOGLE_DRIVE')
error. What am i doing wrong?
//===============================================================================
// Initial State
//===============================================================================
const initialState = {
users: {
GOOGLE_DRIVE: [],
},
}
const state = { ...initialState }
//===============================================================================
// Actions
//===============================================================================
const actions = {
//-------------------------------------------------------------------
// Login user
//-------------------------------------------------------------------
async login(state, payload) {
console.log('login vue')
try {
switch (payload) {
case 'GOOGLE_DRIVE': {
console.log('payload', payload)
const GoogleUser = await googleAuth.signIn()
const user = {
isSignedIn: GoogleUser.isSignedIn(),
name: GoogleUser.getBasicProfile().getName(),
image: GoogleUser.getBasicProfile().getImageUrl(),
email: GoogleUser.getBasicProfile().getEmail(),
accessToken: GoogleUser.getAuthResponse().access_token,
meta: GoogleUser.getAuthResponse(),
isActive: false
}
console.log('user', user)
//state.users[payload] = user
//state.commit('users', { GOOGLE_DRIVE: user })
console.log('user', state)
break;
}
default:
throw Error(`invalid drive name, ${payload}`);
}
} catch (err) {
console.error(`[login]: `, err);
}
},
}
//===============================================================================
// Mutations
//===============================================================================
const mutations = {
//-------------------------------------------------------------------
// Reset State
//-------------------------------------------------------------------
[RESET_STATE]() {
Object.keys(initialState).forEach(key => { state[key] = initialState[key] })
}
}
//===============================================================================
// Getters
//===============================================================================
const getters = {
users(state, payload, drive) {
console.log('opayload', payload)
console.log('drive', drive)
console.log('get state', state)
state.users = { }
},
}
CodePudding user response:
The first argument in an action is the Vuex context. You've named it state
and tried to access state.users
from it, so I believe you're incorrectly assuming it's the Vuex state. Note users
does not exist in the context, so it would be undefined
, and users['GOOGLE_DRIVE']
would then lead to the error you observed:
const actions = {
async login(state, payload) {
^^^^^ ❌ arg1 is context, not state
⋮
state.users[payload] = user // ❌ state.users is undefined
}
}
However in Vuex 3, actions should not be mutating state directly. That should be moved into a Vuex mutation:
const mutations = {
'SET_USERS'(state, users) {
state.users = { ...state.users, ...users }
}
}
Then the action could invoke the mutation through the context's commit()
:
const actions = {
async login({ commit }, payload) {
⋮
commit('SET_USERS', { GOOGLE_DRIVE: user })
}
}
Finally, your getter is not declared correctly. The arguments and the state assignment within it make your getter look like a mutation. To fix the getter:
- Getters receive
state
as its 1st argument and any other getters as the 2nd argument, so remove the other arguments. - It needs to return something, typically based on its
state
argument (e.g., theusers
getter should returnstate.users
). - Getters should not mutate the Vuex state, so remove the
state.users
assignment.
The getter should look like this:
const getters = {
users: state => state.users,
}