Search code examples
javascriptecmascript-6async-awaites6-promisemap-function

Unsure how to resolve a pending promise?


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!


Solution

  • 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;
    };