1

I am new to VueJS and NuxtJS. I want to set up the following route:

https://example.com/resources/:sections/:categories

Whenever a user visits a url such as https://example.com/resources/samsung/laptop, I want to do an HTTP GET request to a REST API to download all the sections and categories and save it to a "global variable". Whenever users click on any <nuxt-link> on my website, NuxtJS will NOT make any more HTTP GET request to REST API unless I have explicitly emptied the "global variable". I read from a few sources that I can achieve this by using a fetch() function to populate a vuex store.

Hence I made the following two files:

~/pages/resources/_.vue

<template>
  <div>
    <nuxt-link to="/resources/samsung/laptop">Samsung Laptop</nuxt-link>
    <nuxt-link to="/resources/samsung/mouse">Samsung Mouse</nuxt-link>
    <nuxt-link to="/resources/samsung/computer">Samsung Computer</nuxt-link>
    <nuxt-link to="/resources/motorola/computer">Motorola Computer</nuxt-link>
    <nuxt-link to="/resources/motorola/laptop">Motorola Laptop</nuxt-link>
    <nuxt-link to="/resources/motorola/phone">Motorola Phone</nuxt-link>
  </div>
</template>

<script>
export default {
  middleware: 'auth',
  async fetch({ $axios, $auth }) {

    console.log('resource store', this.resources);

    const sections = await $axios.get('/sections')
    const categories = await $axios.get('/categories')
    const resources = await $axios.get(`/resources/${$auth.user.id}/list`)
    
    this.resources = {
      sections: sections.data.data,
      categories: categories.data.data,
      resources: resources.data,
      user: $auth.user,
    }
  },
  computed: {
    resources: {
        get(){
          return this.$store.state.resources
        },
        set(val){
          this.$store.dispatch('setResources',val)
        }
    },
  },
}
</script>

~/store/resources.js

export const state=()=>({
  resources:{}
})

export const mutations ={
  SET_RESOURCES(state,payload){
      state.resources=payload
  }
}

export const actions ={
   setResources(context,payload){
        context.commit('SET_RESOURCES',payload)
   }
}

This "almost" does what I want.

  1. When I visit the url https://example.com/resources/samsung/laptop for the first time, my developer tools show resource store undefined and I see my browser successfully fetch data right afterwards. This is what I expect.

  2. When I click on <nuxt-link to="/resources/motorola/computer" />, I see resource store undefined again. This is NOT what I expect. Resource store should already be populated from step 1.

  3. When I click on <nuxt-link to="/resources/motorola/phone" />, I see resource store {Object > sections: etc.... Thiis what I expect. But why did it populate on step 3 and not earlier?

My question is why is the resource store empty on my second nuxt-link click? I expected the resource store to be populated immediately after step 1's nuxt-link click.

What am I doing wrong?

kissu
  • 40,416
  • 14
  • 65
  • 133
John
  • 32,403
  • 80
  • 251
  • 422
  • I'm not sure if this is related, but you're using the `old fetch` if you pass params to the `fetch()` hook. Maybe try to use `this.$axios` and `this.$auth` rather. Then, it's maybe a matter of lifecycle? What did you see in your vue devtools when you click for the 2nd time? Do you have a Github link or a [repro]? – kissu Aug 16 '21 at 09:25

0 Answers0