0
votes

In my mounted i call axios to get profile datail, then if success i send payload to 'set_account' vuex.

For recovery this data i use MapGetters (currentAccount) in computed.

When thy recover this data ex: currentAccount.profile.name in console i receive: TypeError: Cannot read property 'name' of undefined

But i receive data. Why this error?

Vuex dev tools image

App.vue

<template>
  <!-- Don't drop "q-app" class -->
  <div id="q-app">
    <q-layout ref="layout">
  <!-- Header -->
  <q-toolbar slot="header" v-if="this.$route.path !== '/'">
    <q-btn flat @click="$refs.layout.toggleLeft()">
      <q-icon name="menu" />
    </q-btn>
    <q-toolbar-title>
      Saúde Digital
      <span slot="subtitle">Meu Perfil</span>
    </q-toolbar-title>
  </q-toolbar>
  <!-- Left Side Panel -->
  <div slot="left">
    <q-list no-border link inset-separator>
      <q-list-header>
        Olá: {{currentAccount.profile.name}}.
        <q-icon name="sentiment_very_satisfied"/>
      </q-list-header>
      <q-side-link item to="/docs">
        <q-item-side icon="link" />
        <q-item-main label="Link" sublabel="Some menu link" />
      </q-side-link>
      <q-item @click="logout">
        <q-item-side icon="power_settings_new" />
        <q-item-main label="Logout" />
      </q-item>
    </q-list>
  </div>
  <!-- sub-routes get injected here: -->
  <router-view />
  <!-- Footer -->

</q-layout>
  </div>
</template>

<script>
import {http} from 'src/http/index'
import {mapGetters} from 'vuex'

export default {
  name: 'app',
  beforeMount () {
    this.getProfile()
  },
  computed: {
    ...mapGetters({
      showErros: 'getErrors',
      currentAccount: 'currentAccount'
    })
  },
  methods: {
    getProfile () {
      http.get('profile')
        .then(response => {
          this.$store.dispatch('set_account', response.data)
        })
        .catch(error => console.log(error))
    },
    // If not have localStorage token and path not "/" (login)
    // redirect to root (login)
    logout () {
      this.emptyLocalStorage()
      this.$store.dispatch('remove_user')
      this.$router.go('/')
    },
    emptyLocalStorage () {
      delete localStorage.token
    }
  }
}
</script>

Vuex Store: Auth.js

export default {
  state: {
    account: false,
    errors: false
  },

  getters: {
    currentAccount (state) {
      return state.account
    },
    getErrors (state) {
      return state.errors
    }
  },

  mutations: {
    LOAD_ERRORS (state, payload) {
      state.errors = payload
    },
    LOAD_ACCOUNT (state, payload) {
      state.account = payload
    },
    REMOVE_ACCOUNT (state, payload) {
      state.account = null
    }
  },

  actions: {
    set_errors ({commit}, payload) {
      commit('LOAD_ERRORS', payload)
    },
    set_account ({commit}, payload) {
      commit('LOAD_ACCOUNT', payload)
    },
    remove_account ({commit}) {
      commit('REMOVE_ACCOUNT')
    }
  }
}
1
When mounted occurs, currentAccount.profile.name probably does not exist yet - currentAccount at this point is still the string you set on it 'currentAccount'. This string does not have a property profile. Trying to access name of undefined...connexo
So change the initial value of currentAccount in your data function to { currentAccount: { profile: { name: null } } }connexo
I create one level below like: state: { account: { profile: {} } Thanks for your explanation. Solved.Jhonatan Petronilho
You can also do it in the binding: {{ currentAccount.hasOwnProperty('profile') && currentAccount.profile.hasOwnProperty('name') ? currentAccount.profile.name : '' }}connexo

1 Answers

0
votes

that because on mounting there is no such object as person. First your component is mounted (no person object, error is shown), next Ajax is sent, next component is updated by vuex (now you see information). You have few options here either to check if person object exist and then use it or in better way - describe better default state object.