2

I'm building a Movie website to practice on VueJS. During app initialization, I get a list of movie genres from 3rd-party API. Since this list is needed in several components of the app, I manage and store it via Vuex, like so:

main.js:

new Vue({
  router,
  store,
  vuetify,
  render: h => h(App),
  created () {
    this.$store.dispatch('getGenreList')
  }
}).$mount('#app')

Vuex's index.js:

export default new Vuex.Store({
  state: {
    genres: []
  },
  mutations: {
    setGenreList (state, payload) {
      state.genres = payload
    }
  },
  actions: {
    async getGenreList ({ commit }) {
      try {
        const response = await api.getGenreList() // axios call defined in api.js
        commit('setGenreList', response)
      } catch (error) {
        console.log(error)
      }
    }
  }
})

Now, in my Home view, I want to retrieve a list of movies for each genres, something like this:

Home.vue:

<script>
import { mapState } from 'vuex'
import api from '../api/api'

export default {
  name: 'home',
  data () {
    return {
      movies: null
    }
  },
  computed: {
    ...mapState({
      sections: state => state.genres
    })
  },
  async mounted () {
    const moviesArray = await Promise.all(
      this.sections.map(section => {
        return api.getMoviesByGenre(section.id)
      })
    )
    this.movies = moviesArray
  }

}
</script>

The issue here is that, on initial load, sections===[] since genres list hasn't been loaded yet. If I navigate to another view and come back, sections holds an array of genres objects as expected.

Question: How can I properly wait on sections to be loaded with genres? (since the getGenreList action isn't called from that component, I can't use this method)

I was thinking in implementing the movie list retrieval in a Watcher on sections instead of in mounted() but not sure if it's the right approach.

LundinCast
  • 9,412
  • 4
  • 36
  • 48

1 Answers1

2

Yep, it is right approach, that's what watchers are for.

But if you only can... try to do actions like this one inside one component family. (parent passing props to children, controlling it);

You can read this article, about vuex - https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/. It will maybe clarify this idea. Just simply don't store in vuex everything, cause sometimes it' does not make sense

https://v2.vuejs.org/v2/api/#watch - for this one preferably you should use immedaite flag on watcher and delete mounted. Watcher with immedaite flag is kinda, watcher + created at once

tony19
  • 125,647
  • 18
  • 229
  • 307
BigKamil5
  • 295
  • 3
  • 11