Home > database >  Using `await` within a .map works but seems to skip the parent's `await` functionality
Using `await` within a .map works but seems to skip the parent's `await` functionality

Time:02-04

I have an rss.xml.js file that runs this script in a project using the astro framework.

import rss from "@astrojs/rss";
import { fetchFeed } from "../lib/api";

export async function get(context) {
  const posts = await fetchFeed();

  return rss({
    title: "My Online Store",
    description: "Online For Everyone",
    site: context.site,
    items: posts.map((post) => ({
      title: post.title,
      pubDate: Date.now(),
      description: post.description,
      // customData: post.data.customData,
      // Compute RSS link from post `slug`
      // This example assumes all posts are rendered as `/blog/[slug]` routes
      link: post.url,
    })),
  });
}

normally the fetchFeed function has its await functionality and it works fine. However in this particular case I had to make the map method too as an async. That, to me, seems to be the only difference between my previous site, where this worked and the current one, where it's not working.

export const fetchFeed = async function () {
  const allPosts = await import.meta.glob("./../pages/**/*.md");
  // console.log("allPosts", allPosts);
  const posts = Object.values(allPosts).map(async (postData) => {
    const post = await postData();
    // console.log("inside", post.frontmatter);
    return { ...post.frontmatter, url: post.url };
  });

  return posts;
};

When I console.log the posts (in the rss.xml.js) I realise that posts doesn't exist as the fetchFeed function call is not yet resolved. And it resolves after the rss() function has been called.

I assumed the await keyword would delay the return till it was resolved... but that's not what is happening.

Could someone help me and point out what I am doing wrong? I am not very good with Promises and I would appreciate some help.

Regards,

Alim

CodePudding user response:

Your posts is an array of Promises. You need to await that.

  const posts = await Promise.all(Object.values(allPosts).map(async (postData) => {
    const post = await postData();
    // console.log("inside", post.frontmatter);
    return { ...post.frontmatter, url: post.url };
  }));

CodePudding user response:

Use promise.all

Code will be like this:

export async function get(context) {
  const postsPromises = await fetchFeed();

  const posts = await Promise.all(postsPromises);

  return rss({
    title: "My Online Store",
    description: "Online For Everyone",
    site: context.site,
    items: posts.map((post) => ({
      title: post.title,
      pubDate: Date.now(),
      description: post.description,
      link: post.url,
    })),
  });
}

  • Related