Home > other >  Vuex state not setting to getter
Vuex state not setting to getter

Time:11-01

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:

  1. Getters receive state as its 1st argument and any other getters as the 2nd argument, so remove the other arguments.
  2. It needs to return something, typically based on its state argument (e.g., the users getter should return state.users).
  3. 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,
}

demo

  • Related