NodeJS Airtable: Async function not waiting for promise resolution

I’m having trouble with my NodeJS app that fetches data from Airtable. The async function doesn’t seem to wait for the promise to resolve before moving on. Here’s what I’m dealing with:

async function fetchAirtableInfo(identifier) {
  return await airtableConnection('Information')
    .select({
      filterByFormula: `{identifier} = \"${identifier}\"`,
    })
    .firstPage((error, results) => {
      if (error) {
        console.error(error);
        return {};
      }
      console.log(results[0].fields);
      return results[0].fields;
    });
}

items.map(async (item) => {
  displayInfo = getDisplayInfo(item);
  info = await fetchAirtableInfo(displayInfo.identifier);
  console.log(info);
});

When I run this, the console shows:

undefined
undefined
undefined
{ identifier: 'A', name: 'Item A', image: '...' }
{ identifier: 'B', name: 'Item B', image: '...' }
{ identifier: 'C', name: 'Item C', image: '...' }

Why are the first three outputs undefined? How can I make sure the function waits for the Airtable data before logging?

I’ve dealt with similar Airtable issues in Node.js projects. The problem stems from the mismatch between Airtable’s callback-based API and JavaScript’s promise-based async/await syntax. To resolve this, you need to promisify the Airtable call.

Here’s a solution that worked for me:

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

This approach wraps the Airtable call in a Promise, allowing async/await to work correctly. It also handles potential errors and empty results gracefully. Remember to use proper error handling in your main code as well, perhaps with try/catch blocks around your await calls.

I’ve encountered similar issues when working with Airtable. The crux of the matter is that Airtable’s firstPage method relies on callbacks, so using await directly doesn’t work as expected. In my experience, the solution was to wrap the callback in a Promise. For example:

async function fetchAirtableInfo(identifier) {
  return new Promise((resolve, reject) => {
    airtableConnection('Information')
      .select({ filterByFormula: `{identifier} = "${identifier}"` })
      .firstPage((error, results) => {
        if (error) reject(error);
        else resolve(results[0].fields);
      });
  });
}

This ensures that your async function actually waits for the data to be fetched before moving on. It fixed the undefined outputs in my case. Also, if you’re dealing with numerous Airtable requests, you might consider using a promise-based library like ‘asyncairtable’ to simplify your code.

hey there, looks like ur havin some trouble with async stuff. i had similar issues before. try wrapping ur firstPage method in a new Promise. something like:

return new Promise((resolve, reject) => {
airtableConnection(‘Information’)
.select({…})
.firstPage((error, results) => {
if (error) reject(error);
else resolve(results[0].fields);
});
});

that should fix the undefined problem. good luck!