Unsure how to resolve a pending promise?

Viewed 328

I'm looping through some data and fetching individual navigation items.

If I console.log(navItems) before the return in the getNavItems function, it logs everything I expect.

However, if I log footerData before my return inside getFooterData, I'm returned with an unresolved promise inside my items

[
  { heading: 'Heading 1', items: Promise { <pending> } },
  { heading: 'Heading 2', items: Promise { <pending> } },
  { heading: 'Heading 3', items: Promise { <pending> } },
]

What I'm expecting is something more like:

[
  { heading: 'Heading 1', items: [ {data: 1}, {data: 2}, {data: 3} ] },
]
const getNavitems = async (navItemList) => {
  const navItemIds = navItemList.map(({ sys: { id } }) => id);

  const navItemData = await Promise.all(
    navItemIds.map((id) => client.getEntry(id))
  );

  const navItems = navItemData.map((item) => item.fields);

  return navItems;
};

const getFooterData = async () => {
  const footerDataCollection = await client.getEntry('abcxyz123');

  const footerData = Object.entries(footerDataCollection.fields.sections).map(
    (item) => {
      return {
        heading: item[1].fields.heading,
        items: (() => getNavitems(item[1].fields.item_list))()
      };
    }
  );

  return footerData;
};

Any help would be great as I've been banging my head on this for hours now!

3 Answers

A solution that uses a loop. (Array.prototype.map is tricky with await)

I haven't tested this, since I have no way to do it.

const getNavitems = async (navItemList) => {
  const navItemIds = navItemList.map(({ sys: { id } }) => id);

  const navItemData = await Promise.all(
    navItemIds.map((id) => client.getEntry(id))
  );

  const navItems = navItemData.map((item) => item.fields);

  return navItems;
};

const getFooterData = async () => {
  const footerDataCollection = await client.getEntry('abcxyz123');

  const footerData = Object.entries(footerDataCollection.fields.sections);

  const items = await Promise.all(footerData.map(item => getNavitems(item[1].fields.item_list)));

  for (let i = footerData.length; i--;) {
      footerData[i] = {
          heading: footerData[i][1].fields.heading,
          items: items[i]
      }
  }

  return footerData;
};

Maybe instead items: (() => getNavitems(item[1].fields.item_list))() try items: await getNavitems(item[1].fields.item_list). What the anonymous function exactly is for there?

const footerData = await Promise.all(Object.entries(footerDataCollection.fields.sections).map(
    async (item) => {
      return {
        heading: item[1].fields.heading,
        items: await getNavitems(item[1].fields.item_list)
      };
    }
  ));

In items: (() => getNavitems(item[1].fields.item_list))(), you need to insert another await.

items: (async () => await getNavitems(item[1].fields.item_list))()

getNavItems is an async function. Therefore, you must use await to get the return value.

Related