Hey everyone, I’m stuck with a problem using a database API in my Node.js project. I’ve got two tables: one for advisors and another for positions. I’m trying to get the position name for each advisor using a search function. The goal is to send this info to my view.
Here’s what I’ve done so far:
router.get('/', async (req, res) => {
const pageTitle = 'Advisor List'
const fetchAdvisors = async () => {
const advisorList = await advisorTable
.select({ limit: 6, view: 'Main View' })
.eachPage((advisors, getMore) => {
advisors.forEach(advisor => {
positionTable.find(advisor.fields['Current Role'], (error, position) => {
if (error) {
console.error('Oops! Something went wrong:', error)
return
}
advisor.fields.position = position.fields.Title
return advisor
})
})
getMore()
})
return advisorList
}
try {
const advisors = await fetchAdvisors()
console.log(advisors)
res.render('advisorList', { pageTitle, advisors })
} catch (error) {
console.error('Error fetching advisors:', error)
res.status(500).send('Something went wrong')
}
})
But when I run this, I keep getting a ‘Promise Pending’ message. Any ideas on what I’m doing wrong? Thanks in advance for your help!
I’ve faced similar issues with asynchronous data retrieval in database APIs. The problem lies in how you’re handling the asynchronous operations within your eachPage
callback.
Here’s what I’d suggest based on my experience:
- Convert
positionTable.find
to a promise-based function using util.promisify
.
- Use
Promise.all
to wait for all position lookups to complete before calling getMore()
.
- Accumulate the advisors in an array and return it after all pages are processed.
Here’s a rough outline of how you could restructure your code:
const util = require('util');
const findPosition = util.promisify(positionTable.find.bind(positionTable));
const fetchAdvisors = async () => {
let allAdvisors = [];
await advisorTable.select({ limit: 6, view: 'Main View' }).eachPage(async (advisors, getMore) => {
const advisorPromises = advisors.map(async (advisor) => {
try {
const position = await findPosition(advisor.fields['Current Role']);
advisor.fields.position = position.fields.Title;
} catch (error) {
console.error('Error fetching position:', error);
}
return advisor;
});
const processedAdvisors = await Promise.all(advisorPromises);
allAdvisors = allAdvisors.concat(processedAdvisors);
getMore();
});
return allAdvisors;
};
// Use fetchAdvisors in your route handler
This approach should resolve your ‘Promise Pending’ issue and ensure all data is properly retrieved before rendering the view.
hey there! looks like ur struggling with async stuff. i’ve had similar issues before. the problem is mixing callbacks and promises. try converting positionTable.find to a promise with util.promisify. then use Promise.all to handle all the lookups at once. something like this:
const findPosition = util.promisify(positionTable.find.bind(positionTable));
const fetchAdvisors = async () => {
let allAdvisors = [];
await advisorTable.select({limit: 6, view: 'Main View'}).eachPage(async (advisors, nextPage) => {
const promises = advisors.map(async advisor => {
const position = await findPosition(advisor.fields['Current Role']);
advisor.fields.position = position.fields.Title;
return advisor;
});
allAdvisors = allAdvisors.concat(await Promise.all(promises));
nextPage();
});
return allAdvisors;
};
hope this helps!
I see you’re having trouble with asynchronous operations in your database API. The issue stems from mixing callbacks and promises, which can lead to timing problems. To fix it, convert the callback-based positionTable.find into a promise-based function with util.promisify. Then, use Promise.all to handle all the asynchronous position lookups concurrently. Accumulate the advisors in an array and return it after processing all pages.
Here’s a basic structure:
const util = require('util');
const findPosition = util.promisify(positionTable.find.bind(positionTable));
const fetchAdvisors = async () => {
let allAdvisors = [];
await advisorTable.select({ limit: 6, view: 'Main View' }).eachPage(async (advisors, fetchNextPage) => {
const advisorPromises = advisors.map(async (advisor) => {
const position = await findPosition(advisor.fields['Current Role']);
advisor.fields.position = position.fields.Title;
return advisor;
});
allAdvisors = allAdvisors.concat(await Promise.all(advisorPromises));
fetchNextPage();
});
return allAdvisors;
};
This approach should resolve your ‘Promise Pending’ issue and ensure that all data is properly retrieved before rendering the view.