I’m working with an Airtable setup that has two connected tables - Courses and Learners. When someone looks up a specific learner, I need to find their courses and then get all other learners in those same courses.
My current approach works but feels really messy. I’m using multiple loops and setTimeout functions to handle the async calls. Here’s what I’m trying to accomplish:
- Search for a learner by name
- Get their enrolled courses (need actual course names, not IDs)
- For each course, find all other enrolled learners
- Return everything together
Here’s my current implementation:
app.get('/learner/:name', async (req, res) => {
try {
const apiUrl = 'https://api.airtable.com/v0/appXYZ123/learners';
const searchFilter = `?filterByFormula=SEARCH("${req.params.name}", {FullName})`;
const response = await fetch(`${apiUrl}${searchFilter}`, {
headers: { Authorization: `Bearer ${process.env.API_KEY}` }
});
const result = await response.json();
const learnerRecord = result.records[0];
const enrolledCourses = learnerRecord.fields['Courses'];
let courseNames = [];
let allLearnerIds = [];
let classmates = [];
// Get course names from IDs
for (let course of enrolledCourses) {
airtableBase('Courses').find(course, (error, courseRecord) => {
if (error) throw error;
courseNames.push(courseRecord.fields.CourseName);
});
}
// Get all learner IDs for each course
for (let course of enrolledCourses) {
airtableBase('Courses').find(course, (error, courseRecord) => {
if (error) throw error;
allLearnerIds.push(courseRecord.fields['EnrolledLearners']);
});
}
// Convert learner IDs to actual names
setTimeout(() => {
for (let i = 0; i < allLearnerIds.length; i++) {
let namesInCourse = [];
for (let learnerId of allLearnerIds[i]) {
airtableBase('Learners').find(learnerId, (error, learnerRecord) => {
if (error) throw error;
namesInCourse.push(learnerRecord.fields.FullName);
});
}
classmates.push(namesInCourse);
}
}, 800);
setTimeout(() => {
const finalResult = courseNames.map((courseName, index) => {
return {
course: courseName,
peers: classmates[index]
};
});
res.json({ data: finalResult, searchedLearner: req.params.name });
}, 1200);
} catch (error) {
res.json({ error: 'Learner not found in database' });
}
});
Is there a cleaner way to handle these nested queries? The setTimeout approach feels really hacky. Any suggestions for making this more efficient would be great!