Nested lists (list > list > detail page) with Airtable

In this tutorial, we'll show you how to work with nested lists with data stored in Airtable. This is useful when we have a database with many items, each of them belonging to one or several categories. This will allow us to create this setup: list page (all items) > list page (items by category) > detail page in our apps.

We'll use a database with data from several cities, each of them belonging to a different world region. Copy this link:

And this Figma file:

We'll create four different requests:

  • A request to get a list with all the world regions (Regions - List)

  • A request to get a list with all the cities (Cities - List)

  • A request to get the details of a single city (Cities - Detail)

  • A request to get a list with the cities belonging to a particular region (Cities in Region)

To create the last request (Cities in Region), we'll leverage Airtable's formulas, by filtering the data in the Cities table according to the region name.

If you are new to Bravo, we recommend you check out this page before following this tutorial, to get some knowledge on how the Bravo Data Library and Data Binding work.

The Airtable database consists of two tables (Cities and Regions) and a linked record field to bind each city with its region. The Cities table will contain the following data:

  • City name

  • Population

  • Summer temperature

  • Winter temperature

  • Living cost (euros)

  • Regions (linked record field to Regions table)

  • region_name (lookup field for the previous linked record field)

The Regions table will contain a field for the region name and a linked record field that will be generated after creating the linked field in the Cities table.

๐Ÿ— Creating the API requests in the Data Library

Once we have the data on Airtable, we'll create the requests mentioned above. In the Data Library, click on Create New Collection and use the Airtable wizard. This will generate two sample requests (list and detail) per table, so 4 requests in total.

1. Request: Regions - List

This request will list all the items in the Regions table. Under Selected Data, change the Name of data path .data.records[].fields.region with the variable name region_name, as we'll use this variable later in the Cities in Region request (see screenshot below).

2. Request: Cities - List

This request will list all the items in the Cities table. We can leave it as is.

3. Request: Cities - Detail

This request will return the details of a particular city in the Cities table, identified by its ID. We can leave it as is.

4. Request: **Cities in Region**

Finally, we'll create the requests that returns a list with the cities belonging to a specific region. We can change the name of the request named "Regions - Detail" generated with the Airtable wizard, as we won't need it.

Our goal here will be to filter the data of the Cities table, and return only the cities that belong to a specific region. The data corresponding to the name of that specific region will be stored in a variable called ${region_name}, which we defined in the Regions - List request.

We'll change the request URL and set this one:'${region_name}'%2Carrayjoin(region_name))

Here, we are using Airtables's filterByFormula parameter, which can be used to configure an Airtable formula to filter the data from the tables. The %2C in the URL is an encoded comma, the formula in plain text would be search('${region_name}',arrayjoin(region_name)). You can use this Airtable API encoder to generate the URL.

In this URL, the formulas search and arrayjoin are being used. With search, we specify first a string to search (in this case, we're using the ${region_name} variable we defined in the Regions - List request), and then the term where we want to search. This will be obtained by executing another formula, arrayjoin, over the column named region_name in our Cities table (note that it has the same name as the previously mentioned variable).

This column (region_name) contains a data type called lookup, which is associated to the linked record we have. We use it here to retrieve the name of the region a city belongs to, as the linked record field only returns the ID string of that element when making an API call. The lookup field allows us to obtain a string with the region name from the API.

Here, you can see the "region_name" lookup field we are using to filter the data of the Cities table. The "Regions" field would be the linked record associated to the lookup field.

The reason we need to use arrayjoin is that the region_name field consists of an array with a single element, which is the name of the region we mentioned before (this is the way the Airtable API returns the lookup fields).

The lookup field obtained from the API. We need to use the "arrayjoin" formula in the filter to get the string contained in that single-element array.

Once we set this filterByFormula parameter, we'll be able to link a screen listing all the regions, bound to the Regions - List request, with a screen listing all the cities that belong to the region we clicked in the previous screen. This last screen will be bound to the Cities in Region request.

๐Ÿ— Binding the data to the app UI

You can follow from this point the World Cities tutorial to bind the API requests with the design shown in that tutorial (we'll also have a screen to display a list with all the cities, and another one to display the city details). Note that the variable and request names shown in that tutorial will be different from the ones we just created, as another backend is being used.

Happy Bravorizing! ๐Ÿฅณ

Last updated