drake035
drake035

Reputation: 2877

State variable triggers error when displaying it in template as it's temporarily null when component mounts

My user state variable is an object having several properties such as first_name. I want to display some of these properties in my component template.

I'm assign my state variable to a computed property which I use in template thus:

<template>
  <div>
    {{ user.first_name }}
  </div>
</template>

<script>
import { mapState } from "vuex";

export default {
  computed: {
    ...mapState({
      user: state => state.dashboard.user
    })
  },
  beforeMount () {
    this.$store.dispatch("dashboard/getUser");
  }
};
</script>

Although it works, I get the following error in console:

Error in render: "TypeError: Cannot read property 'title' of null"

I suppose it's because user is null for a split second as component mounts, till it receives info that Vue correctly displays in template. How to avoid the error though?

[EDIT] here are the relevant part of the store:

state: {
  user: null
},
...
actions: {
  async getUser({ commit }) {
    let user = await axios.get(`user`).catch(console.error);
    commit("SET_USER", user);
    return user;
  }
},

Upvotes: 0

Views: 50

Answers (2)

Gabriel Osuobiem
Gabriel Osuobiem

Reputation: 30

Ok. I've rewritten the code.

store.js

state: {
  user: ''
},
mutations: {
  SET_USER: (state, user) => {
    state.user = user
  }
},
actions: {
  getUser: (context, user) => {
    axios.get('url/to/server')
         .then(res => {
            context.commit('SET_USER', res.data)
         })
         .catch(error => {
            console.log(error)
         })
  }
}

Now in your root component (App.vue for example)

import {mapActions} from 'vuex'
export default{
  ...
  mounted() {
    this.getUser()
  },
  methods: {
    ...mapActions(['getUser'])
  }
}

In the component, you wish to use the user data

<template>
  <div>
    {{user.first_name}}
  </div>
<template/>

import {mapState} from 'vuex'
export default{
  computed: {
    ...mapState(['user'])
  }
}

This will work. Hope it helps.

Upvotes: 0

Craig Harshbarger
Craig Harshbarger

Reputation: 2233

In your mapped getter you could default to an empty object like

state => state.dashboard.user || {}

That way things like user.first_name would be undefined rather than attempting to look for a property on the value null

Upvotes: 1

Related Questions