skip to Main Content

In my application I have a seller page which displays products listed by that seller. I am using asyncData to get all data required for the page (better for SEO)

asyncData ({params, app, error }) {

    return app.$axios.$get(`/seller/${params.username}`).then(async sellerRes => {

        let [categoriesRes, reviewsRes, productsRes] = await Promise.all([
            app.$axios.$get(`/categories`),
            app.$axios.$get(`/seller/${params.username}/reviews`),
            app.$axios.$get(`/seller/${params.username}/products`)
        ])

        return {
            seller: sellerRes.data,
            metaTitle: sellerRes.data.name,
            categories: categoriesRes.data,
            reviewsSummary: reviewsRes.summary,
            products: productsRes.data,
        }

    }).catch(e => {
        error({ statusCode: 404, message: 'Seller not found' })
    });
},

Although this method does the job intended, I can’t help but think I am doing this wrong.

When navigating to the page the nuxt progress bar displays twice (which is odd).

I’ve been searching for a while now to try and find examples of multiple requests in asyncData but there’s not much out there.

Maybe I’m not supposed to call multiple requests in asyncData?

3

Answers


  1. Maybe so?

    asyncData ({params, app, error }) {
    
        return app.$axios.$get(`/seller/${params.username}`).then(sellerRes => {
            return Promise.all([
                app.$axios.$get(`/categories`),
                app.$axios.$get(`/seller/${params.username}/reviews`),
                app.$axios.$get(`/seller/${params.username}/products`)
            ]).then((categoriesRes, reviewsRes, productsRes) => {
                return {
                    seller: sellerRes.data,
                    metaTitle: sellerRes.data.name,
                    categories: categoriesRes.data,
                    reviewsSummary: reviewsRes.summary,
                    products: productsRes.data,
                }
            })
        }).catch(e => {
            error({ statusCode: 404, message: 'Seller not found' })
        });
    
    },
    

    This is a chain of promises. The first promise tries to get information about the seller, if the request is successful, then a new request is created that will wait for the rest of the information.

    Method asyncData will wait for all promises to complete and return the result of the call.

    Login or Signup to reply.
  2. Actually, you can, using the async await, which, looks a lot cleaner too.

    <template>
      <div class="container">
        <h1>Request 1:</h1>
        <h1>{{ post.title }}</h1>
        <pre>{{ post.body }}</pre>
        <br />
        <h1>Request 2:</h1>
        <h1>{{ todos.title }}</h1>
        <pre>{{ todos.completed }}</pre>
      </div>
    </template>
    
    <script>
    import axios from "axios";
    
    export default {
      async asyncData({ params }) {
        // We can use async/await ES6 feature
        const posts = await axios.get(
          `https://jsonplaceholder.typicode.com/posts/${params.id}`
        );
        const todos = await axios.get(
          `https://jsonplaceholder.typicode.com/todos/${params.id}`
        );
        return { post: posts.data, todos: todos.data };
      },
      head() {
        return {
          title: this.post.title
        };
      }
    };
    </script>
    

    here is a working sandbox of it. (don’t forget to add a value for :id route param)

    Login or Signup to reply.
  3. Try to use async await, this is how you can run both requests in parallel:

    async asyncData ({ $axios }) {
      const [categoriesRes, articlesRes] = await Promise.all([ 
        $axios.get('/fetch/categories'),
        $axios.get('/fetch/articles'),
      ])
    
      return {
        categories: categoriesRes.data,
        articles: articlesRes.data,
      }
    },
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search