javascript - Vuex getter returns undefined - Stack Overflow

I have a vue app using vex to store site wide data I get the user info and put it into the state on the

I have a vue app using vex to store site wide data I get the user info and put it into the state on the before create life cycle method like so:

const app = new Vue({
    el: '#app',
    store,
    beforeCreate(){
        store.dispatch('currentUser');
    }
});

In my user module I have a getter that gets the name of the user like below:

const getters = {
    getName(state){
        return state.user.name;
    }
};

In my ponents I am trying to access the getter to display the name of the user in the ponent. When I look into the Vue Chrome dev tools the getter is not undefined, but when I console log the getter results like so it says undefined.

mounted(){
    console.log(store.getters.getName);
},

It seems like the ponent is loading before the state is loaded. I am getting the user info using axios. I am really confused on how to solve this since I can not call the action to get the user data any sooner that I know of.

If in my getter method I do:

state.user

I get this:

{ "id": 1, "name": "Test" }

But when I try to get name I get undefined

Here is the store:

import axios from "axios/index";

const state = {
    user: {},
};

const mutations = {
    FETCH_USER(state,user){
        state.user = user;
    },
    UPDATE_AVATAR(state,avatar){
        state.user.avatar = avatar;
    }
};

const getters = {
    getName(state){
      return state.user.name
    },
    avatar(state){
        return state.user.avatar;
    },
    userSocialNetworks(state){
        //return state.user.social_networks
    },
    schoolName(state){
        return state.user.school
    },
    schoolAbout(state){
        return state.user.school.about
    },
    schoolAddress(state){
        return state.user.school.address
    }
};

const actions = {
    currentUser: ({mit}) => {
        axios.get('/api/user').then(response => {
            mit('FETCH_USER', response.data);
        });

    }
}

export default {
    state,
    getters,
    actions,
    mutations

}


 {"user":{"user":{"name":"Test","email":"[email protected]","avatar":"","city":null,"state":null,"zip":null,"address":null,"lat":null,"long":null,"role":"school","school":{"id":1,"about":null,"header":null,"name":"Test","user_id":1,"created_at":"2018-06-06 19:48:16","updated_at":"2018-06-06 19:48:16"},"following":[],"followers":[],"social_networks":[{"id":4,"user_id":1,"social_network_id":1,"network_url":"test/k","created_at":"2018-06-06 23:11:09","updated_at":"2018-06-06 23:15:19"},{"id":5,"user_id":1,"social_network_id":2,"network_url":"test/k","created_at":"2018-06-06 23:15:19","updated_at":"2018-06-06 23:15:19"},{"id":6,"user_id":1,"social_network_id":5,"network_url":"test/k","created_at":"2018-06-06 23:16:15","updated_at":"2018-06-06 23:16:15"}]}},"socialNetowrks":{"available_networks":[{"id":1,"network_name":"Facebook","created_at":null,"updated_at":null},{"id":2,"network_name":"Instagram","created_at":null,"updated_at":null},{"id":5,"network_name":"Twitter","created_at":null,"updated_at":null}]}}

I have a vue app using vex to store site wide data I get the user info and put it into the state on the before create life cycle method like so:

const app = new Vue({
    el: '#app',
    store,
    beforeCreate(){
        store.dispatch('currentUser');
    }
});

In my user module I have a getter that gets the name of the user like below:

const getters = {
    getName(state){
        return state.user.name;
    }
};

In my ponents I am trying to access the getter to display the name of the user in the ponent. When I look into the Vue Chrome dev tools the getter is not undefined, but when I console log the getter results like so it says undefined.

mounted(){
    console.log(store.getters.getName);
},

It seems like the ponent is loading before the state is loaded. I am getting the user info using axios. I am really confused on how to solve this since I can not call the action to get the user data any sooner that I know of.

If in my getter method I do:

state.user

I get this:

{ "id": 1, "name": "Test" }

But when I try to get name I get undefined

Here is the store:

import axios from "axios/index";

const state = {
    user: {},
};

const mutations = {
    FETCH_USER(state,user){
        state.user = user;
    },
    UPDATE_AVATAR(state,avatar){
        state.user.avatar = avatar;
    }
};

const getters = {
    getName(state){
      return state.user.name
    },
    avatar(state){
        return state.user.avatar;
    },
    userSocialNetworks(state){
        //return state.user.social_networks
    },
    schoolName(state){
        return state.user.school
    },
    schoolAbout(state){
        return state.user.school.about
    },
    schoolAddress(state){
        return state.user.school.address
    }
};

const actions = {
    currentUser: ({mit}) => {
        axios.get('/api/user').then(response => {
            mit('FETCH_USER', response.data);
        });

    }
}

export default {
    state,
    getters,
    actions,
    mutations

}


 {"user":{"user":{"name":"Test","email":"[email protected]","avatar":"http://www.gravatar./avatar/xxxx=300","city":null,"state":null,"zip":null,"address":null,"lat":null,"long":null,"role":"school","school":{"id":1,"about":null,"header":null,"name":"Test","user_id":1,"created_at":"2018-06-06 19:48:16","updated_at":"2018-06-06 19:48:16"},"following":[],"followers":[],"social_networks":[{"id":4,"user_id":1,"social_network_id":1,"network_url":"test./k","created_at":"2018-06-06 23:11:09","updated_at":"2018-06-06 23:15:19"},{"id":5,"user_id":1,"social_network_id":2,"network_url":"test./k","created_at":"2018-06-06 23:15:19","updated_at":"2018-06-06 23:15:19"},{"id":6,"user_id":1,"social_network_id":5,"network_url":"test./k","created_at":"2018-06-06 23:16:15","updated_at":"2018-06-06 23:16:15"}]}},"socialNetowrks":{"available_networks":[{"id":1,"network_name":"Facebook","created_at":null,"updated_at":null},{"id":2,"network_name":"Instagram","created_at":null,"updated_at":null},{"id":5,"network_name":"Twitter","created_at":null,"updated_at":null}]}}
Share Improve this question edited Jun 7, 2018 at 2:52 John Freedom asked Jun 7, 2018 at 0:33 John FreedomJohn Freedom 4814 gold badges6 silver badges11 bronze badges 19
  • 1 you need to use this.$store.getters.getName within ponents – Derek Pollard Commented Jun 7, 2018 at 0:35
  • What is the difference – John Freedom Commented Jun 7, 2018 at 0:46
  • 4 The difference is one is undefined and the other isn't – Derek Pollard Commented Jun 7, 2018 at 0:47
  • @Derek I get this error using store that way Error in mounted hook: "TypeError: Cannot read property 'name' of undefined" – John Freedom Commented Jun 7, 2018 at 0:48
  • That means state.user is undefined – Derek Pollard Commented Jun 7, 2018 at 0:59
 |  Show 14 more ments

4 Answers 4

Reset to default 3

You are facing two big issues here:

  1. You should not update the object directly in the vuex store or you'll lose reactivity

So make sure you declare all of your state correctly and you assign to objects instead of overwriting them

import assignDeep from 'assign-deep'; //Since you have nested structure you will need this

const state = {
    user: {
       name: '',
       school: {
          about: '',
          address: '',
       },
       // Make sure all properties are defined
    },

};

const mutations = {
    FETCH_USER(state,user){
        assignDeep(state.user, user);
    },
    UPDATE_AVATAR(state,avatar){
        state.user.avatar = avatar;
    }
};
  1. You are trying to access a property that is asynchronously defined on the state and using it synchronously (before it exists)

First make use of the mapGetters utility of vuex for easier usage

import { mapGetters } from 'vuex';
//... In ponent definition
puted: {
  ...mapGetters({name: 'getName'})
}

Since this is a vue puted property, your ponent will rerender when it gets defined and everything should display properly you just need to make sure you handle the case when it's empty and maybe display a loading screen until it is

For example

<template>
  <div v-if="!name" class="loading"></div>
  <div v-else>{{name}}</div>
<template>

You're also free to just wait for the property to update

Do not use it in the mounted hook as it will still be the default value there

Instead use a watcher or a puted property depending on your needs

watch: {
  name: {
    handler(name, oldName) {
      if (name) {
        //Do something
      }
    },
    immediate: true
  }
}

First of all, methods hasn't been initialized yet in beforeCreate hook. The easiest way around this it to use the created hook instead:

const app = new Vue({
    el: '#app',
    store,
    created(){
        store.dispatch('currentUser'); // considering you have properly imported and exported vuex
    }
});

In your ponent

import {mapGetters} from 'vuex';

export default {
  puted: {
    ...mapGetters(['getName'])
  }
}

Try declaring the specific variables in the store to properly initialize the data:

const state = {
    user: {
        name: '',
        avatar: '',
        school: '',
        ...
    },
};

I was having the same issue you described until I did this.

You can try this:

mounted() {
  setTimeout(() => {
    console.log(store.getters.getName);
  }, 400);
},

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743957372a4536034.html

相关推荐

  • javascript - Vuex getter returns undefined - Stack Overflow

    I have a vue app using vex to store site wide data I get the user info and put it into the state on the

    2天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信