Iterating through several Airtable database connections in Next.js

I need help with async loops in Next.js when working with multiple Airtable databases inside getStaticProps.

I want to iterate through an array of database identifiers like ["appDb001", "appDb002", "appDb003"] and fetch data from each one. Currently my setup works fine with a single database but I’m stuck on handling multiple ones.

Here’s my working code for one database:

const entries = await airtableClient
  .base("appDb001")("Main Data Table")
  .select()
  .firstPage();

const items = entries.map((item) => {
  return {
    location: item.get("Location") || null,
    title: item.get("Title") || null,
    category: item.get("Category") || null,
  };
});

return {
  props: {
    items,
  },
};

I tried a manual approach but it’s not scalable:

export async function getStaticProps() {
  const firstData = await getDataBase("appDb001")
    .select({})
    .firstPage();
  const secondData = await getDataBase("appDb002")
    .select({})
    .firstPage();

  const allData = [];
  allData.push(processRecords(firstData));
  allData.push(processRecords(secondData));

  return {
    props: {
      allData,
    },
  };
}

getDataBase is my helper function:

const getDataBase = (dbId) =>
  client.base(dbId)("Main Data Table");

How can I properly loop through multiple base IDs and wait for each request to complete?

I hit this exact problem a few months ago with multiple Airtable bases for a client dashboard. You’ve got two options: parallel vs sequential execution.

Parallel is faster but hammers the rate limits harder. Use Promise.all:

export async function getStaticProps() {
  const dbIds = ["appDb001", "appDb002", "appDb003"];
  
  const allData = await Promise.all(
    dbIds.map(async (dbId) => {
      const entries = await getDataBase(dbId)
        .select({})
        .firstPage();
      return processRecords(entries);
    })
  );

  return {
    props: {
      allData,
    },
  };
}

This saved me tons of time since all requests fire at once. Just watch Airtable’s API limits if you’re dealing with many bases.

I stick with Promise.all unless I’m hitting rate limits. Then I switch to sequential like Jessica mentioned. Parallel typically cuts my build times in half vs the for-of loop.

Use Promise.all with map instead of manual calls. Try const results = await Promise.all(dbIds.map(async (id) => { const data = await getDataBase(id).select().firstPage(); return processRecords(data); })); - this fetches all DBs at once instead of one by one, so it’s way faster.

Been working with Next.js and Airtable for over a year now and honestly the Promise.allSettled approach saved me countless headaches. Promise.all fails completely if any database throws an error, but Promise.allSettled lets you handle partial failures gracefully.

export async function getStaticProps() {
  const dbIds = ["appDb001", "appDb002", "appDb003"];
  
  const results = await Promise.allSettled(
    dbIds.map(async (dbId) => {
      const entries = await getDataBase(dbId)
        .select({})
        .firstPage();
      return { dbId, data: processRecords(entries) };
    })
  );

  const successfulData = results
    .filter(result => result.status === 'fulfilled')
    .map(result => result.value);

  return {
    props: {
      allData: successfulData,
    },
  };
}

If one database is temporarily down or has issues, your build won’t completely fail. You get data from working databases and can log the failures. Way more robust than other solutions when dealing with external APIs that might have occasional hiccups.

Your manual approach works, but you can make it dynamic with a simple for-of loop. I’ve dealt with similar situations and this is way more readable than Promise.all when you need sequential processing:

export async function getStaticProps() {
  const dbIds = ["appDb001", "appDb002", "appDb003"];
  const allData = [];
  
  for (const dbId of dbIds) {
    const entries = await getDataBase(dbId)
      .select({})
      .firstPage();
    allData.push(processRecords(entries));
  }
  
  return {
    props: {
      allData,
    },
  };
}

This processes databases one at a time, which helps with Airtable’s rate limits. If you don’t care about rate limits and want everything to run in parallel, Promise.all works great too.