2

I am using NuxtJS and I have a NavBar that goes to /website?web=1 and /website?web=2.. When I go from /website?web=1 to /website?web=2 vice versa.. My async fetch is not running at all.

website.vue

async fetch({ store, error, route, params }) {
    let parameters;
    const pageLimit = store.state.websites.pageLimit;
    const offset = params.id ? (params.id - 1) * pageLimit : 0;
    const web = route.query.web;
    try {
      if (web === "1") {
        parameters = `?&is_global=true&offset=${offset}&limit=${pageLimit}`;
      } else if (web === "2") {
        parameters = `?&is_global=false&offset=${offset}&limit=${pageLimit}`;
      } else {
        parameters = `?co_id=${
          route.query.co_id ? route.query.co_id : ""
        }&ca_id=${
          route.query.ca_id ? route.query.ca_id : ""
        }&limit=${pageLimit}&offset=${offset}`;
      }
      await Promise.all([

        store.dispatch("websites/fetchWebsites", parameters)
      ]);
    } catch (e) {
      console.log("Error: " + e);
    }
  },

NavBar.vue

methods: {
    handleClick(tab, event) {
      switch (tab.label) {
        case "1":
          this.$router.push({ name: "index" });
          break;
        case "2":
          this.$router.push("/country");
          break;
        case "3":
          this.$router.push("/website?web=1");
          break;
        case "4":
          this.$router.push("/website?web=2");
          break;
      }
    }
  }
2

2 Answers 2

2

When using Nuxt's fetch(), you need an explicit watcher to listen for route changes.

For a Nuxt component which has async fetch(), if you want it to update when the route changes, then setup a standard watcher.

See docs: https://nuxtjs.org/docs/2.x/features/data-fetching#listening-to-query-string-changes

export default {

  watch: {
      '$route.query': '$fetch'   // This runs $fetch, defined below
  },

  async fetch() {
      // Runs on server load (SSR), or when called (see above)
  }

}

For other context's (or before Nuxt 2.12):

You could explore using watchQuery.

See docs: https://nuxtjs.org/docs/2.x/components-glossary/pages-watchquery/

export default {

  watchQuery(newQuery, oldQuery) {
    // Only execute component methods if the old query string contained `bar`
    // and the new query string contains `foo`
    return newQuery.foo && oldQuery.bar
  }

}

https://nuxtjs.org/docs/2.x/components-glossary/pages-watchquery/

Sign up to request clarification or add additional context in comments.

3 Comments

Nice! so, does it rerender the template or just update the updated data?
It rerenders. Good thing NuxtJS has its native way of dealing this.. Otherwise I will use watcher
Alternatively, you could use a regular watch as well; see docs.
1

async fetch lifecycle is not invoked of query / param update

Sometimes you just want to fetch data and pre-render it on the server without using a store. asyncData is called every time before loading the page component. It will be called server-side once (on the first request to the Nuxt app) and client-side when navigating to further routes doc.

Also, a component does not remount on query / param update, so lifecycles like created / mounted / beforeCreate etc are also not invoked again. This helps in the application's performance as it avoids unnecessary rendering of the entire page where a few data changes would work.

Make a common method

methods: {
 fetchData ({ store, error, route, params }) {
  // your fetch logic here
  let parameters;
  const pageLimit = store.state.websites.pageLimit;
  // ...
 }
}

Call the method in async data

async fetch({ store, error, route, params }) {
 this.fetchData({ store, error, route, params })
}

Call the method again on query change

watch: {
  "$route.query.web": {
    handler () {
      this.fetchData({ store: this.$store, route: this.$route... });
    }
  },

Alternative to watch

beforeRouteUpdate (to, from, next) {
 if (from.name === to.name) { // Call fn only when: route hasn't changed instead just query / params for the route has changed
  this.fetchData({ store: this.$store, route: this.$route... })
 }
},

2 Comments

Thanks for the answer but I came up with a better answer
FYI, to be clear, async fetch and async asyncData are two different things; see docs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.