foopz
foopz

Reputation: 57

Vue - Data not computed in time before mount

I'm learning Vue and I've run into a problem where my data returns undefined from a computed method. It seems that the data is not computed by the time the component is mounted, probably due to the get request - wrapping my this.render() in a setTimeout returns the data correctly. Setting a timeout is clearly not sensible so how should I be doing this for best practice?

Home.vue

export default {
    created() {
        this.$store.dispatch('retrievePost')
    },
    computed: {
        posts() {
            return this.$store.getters.getPosts
        }
    },
    methods: {
        render() {
            console.log(this.comments)
        }
    },
    mounted() {
        setTimeout(() => {
            this.render()
        }, 2000);
    },
}

store.js

export const store = new Vuex.Store({
    state: {
        posts: []
    },
    getters: {
        getPosts (state) {
            return state.posts
        }
    },
    mutations: {
        retrievePosts (state, comments) {
            state.posts = posts
        }
    },
    actions: {
        retrievePosts (context) {
            axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token

            axios.get('/posts')
                .then(response => {
                    context.commit('retrievePosts', response.data)
                })
                .catch(error => {
                    console.log(error)
                })
        }
    }
})

Upvotes: 5

Views: 4474

Answers (1)

Max Sinev
Max Sinev

Reputation: 6019

It is because axios request is still processing when Vue invokes mounted hook(these actions are independent of each other), so state.posts are undefined as expected.

If you want to do something when posts loaded use watch or better computed if it's possible:

export default {
    created() {
        this.$store.dispatch('retrievePost')
    },
    computed: {
        posts() {
            return this.$store.getters.getPosts
        }
    },
    methods: {
        render() {
            console.log(this.comments)
        }
    },
    watch: {
       posts() { // or comments I dont see comments definition in vue object
           this.render();
       }
    }
}

P.S. And don't use render word as methods name or something because Vue instance has render function and it can be a bit confusing.

Upvotes: 3

Related Questions