I’m having trouble with my Node.js app. I’m trying to fetch info from Airtable but the async function isn’t waiting for the promise to resolve before moving on. Here’s what I’ve got:
async function fetchInfo(identifier) {
return await dataSource('Info')
.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) => {
displayInfo = getDisplayInfo(item);
info = await fetchInfo(displayInfo.identifier);
console.log(info);
})
But when I run this, I get:
undefined
undefined
undefined
{
identifier: 'A',
name: 'Item A',
image: '...'
}
{
identifier: 'B',
name: 'Item B',
image: '...'
}
{
identifier: 'C',
name: 'Item C',
image: '...'
}
Why isn’t the async function waiting for the promise to resolve? How can I fix this?
The issue lies in your fetchInfo function. You’re mixing promise-based and callback-based approaches, which is causing the unexpected behavior. Here’s a revised version that should work:
async function fetchInfo(identifier) {
try {
const results = await dataSource('Info')
.select({
filterByFormula: `{identifier} = \"${identifier}\"`
})
.firstPage();
return results[0]?.fields || {};
} catch (error) {
console.error('Error fetching info:', error);
return {};
}
}
This modification uses the async/await syntax consistently, ensuring the promise resolves before returning. The try/catch block handles potential errors gracefully. Remember to use Promise.all if you need to wait for all promises to resolve when mapping over items.
I’ve encountered similar issues when working with Airtable in Node.js. The problem stems from how Airtable’s SDK handles asynchronous operations. To resolve this, you need to promisify the firstPage method. Here’s a solution that worked for me:
const util = require('util');
async function fetchInfo(identifier) {
const select = dataSource('Info').select({
filterByFormula: `{identifier} = \"${identifier}\"`
});
const firstPageAsync = util.promisify(select.firstPage.bind(select));
try {
const results = await firstPageAsync();
return results[0]?.fields || {};
} catch (error) {
console.error('Error fetching info:', error);
return {};
}
}
This approach uses Node’s util.promisify to convert the callback-based firstPage method into a promise-based one. It’s been reliable in my projects and should solve your async issues. Remember to handle potential errors and edge cases in your main function as well.
hey man, your problem is with the firstPage method. it’s using a callback, not returning a promise. try changing it to:
return (await dataSource(‘Info’).select({…}).firstPage())[0]?.fields || {};
this should fix it. good luck with your project!