Async/Await not working properly with Airtable API in Node.js

I’m having trouble with async/await when fetching records from Airtable using Node.js. The await keyword doesn’t seem to wait for the promise to finish before moving on.

Here’s my code:

async function fetchRecord(identifier) {
  return await base("Records")
    .select({
      filterByFormula: `{identifier} = "${identifier}"`,
    })
    .firstPage((error, results) => {
      if (error) {
        console.log(error);
        return {};
      }

      console.log(results[0].fields);
      return results[0].fields;
    });
}
items.map(async (item) => {
  embedInfo = getEmbedInfo(item);

  result = await fetchRecord(embedInfo.identifier);

  console.log(result);
})

The console output shows:

undefined
undefined
undefined
{
  identifier: 'A1',
  name: 'Sample 1',
  image: '...'
}
{
  identifier: 'A2', 
  name: 'Sample 2',
  image: '...'
}
{
  identifier: 'A3',
  name: 'Sample 3', 
  image: '...'
}

The function returns undefined first, then shows the actual data later. How can I make it wait properly?

You’re mixing callback-based APIs with async/await. Airtable’s firstPage() uses callbacks, so await won’t work with it directly. You need to wrap it in a Promise.

Here’s the fix:

async function fetchRecord(identifier) {
  return new Promise((resolve, reject) => {
    base("Records")
      .select({
        filterByFormula: `{identifier} = "${identifier}"`,
      })
      .firstPage((error, results) => {
        if (error) {
          reject(error);
        } else {
          resolve(results[0]?.fields || {});
        }
      });
  });
}

Or just use .all() instead of .firstPage() - it returns a promise directly and makes cleaner code.