0

List Records

by
Published Jun 6, 2022

List the records of a table or of one of its views, with optional formula filter and sort. Follows pagination to return every record.

Script airtable Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 5 days ago
1
//native
2

3
export type DynSelect_base_id = string
4
export type DynSelect_table_id = string
5
export type DynSelect_view = string
6
export type DynSelect_sort_field = string
7

8
// Dropdown of the bases the token can access.
9
export async function base_id(auth: RT.Airtable) {
10
  const options: { value: string; label: string }[] = []
11
  let offset: string | undefined = undefined
12
  do {
13
    const url = new URL("https://api.airtable.com/v0/meta/bases")
14
    if (offset) {
15
      url.searchParams.append("offset", offset)
16
    }
17
    const response = await fetch(url, {
18
      headers: {
19
        Authorization: `Bearer ${auth.apiKey}`,
20
        Accept: "application/json",
21
      },
22
    })
23
    if (!response.ok) {
24
      throw new Error(`${response.status} ${await response.text()}`)
25
    }
26
    const page = (await response.json()) as {
27
      bases: { id: string; name: string }[]
28
      offset?: string
29
    }
30
    options.push(...page.bases.map((b) => ({ value: b.id, label: b.name })))
31
    offset = page.offset
32
  } while (offset)
33
  return options
34
}
35

36
async function listTables(auth: RT.Airtable, base_id: string) {
37
  if (!base_id) {
38
    return []
39
  }
40
  const response = await fetch(
41
    `https://api.airtable.com/v0/meta/bases/${base_id}/tables`,
42
    {
43
      headers: {
44
        Authorization: `Bearer ${auth.apiKey}`,
45
        Accept: "application/json",
46
      },
47
    }
48
  )
49
  if (!response.ok) {
50
    throw new Error(`${response.status} ${await response.text()}`)
51
  }
52
  const { tables } = (await response.json()) as {
53
    tables: {
54
      id: string
55
      name: string
56
      fields: { id: string; name: string; type: string }[]
57
      views: { id: string; name: string }[]
58
    }[]
59
  }
60
  return tables
61
}
62

63
// Dropdown of the tables in the chosen base.
64
export async function table_id(auth: RT.Airtable, base_id: DynSelect_base_id) {
65
  return (await listTables(auth, base_id)).map((t) => ({
66
    value: t.id,
67
    label: t.name,
68
  }))
69
}
70

71
// Dropdown of the views in the chosen table.
72
export async function view(
73
  auth: RT.Airtable,
74
  base_id: DynSelect_base_id,
75
  table_id: DynSelect_table_id
76
) {
77
  const table = (await listTables(auth, base_id)).find((t) => t.id === table_id)
78
  return (table?.views ?? []).map((v) => ({ value: v.id, label: v.name }))
79
}
80

81
// Dropdown of the fields in the chosen table.
82
export async function sort_field(
83
  auth: RT.Airtable,
84
  base_id: DynSelect_base_id,
85
  table_id: DynSelect_table_id
86
) {
87
  const table = (await listTables(auth, base_id)).find((t) => t.id === table_id)
88
  return (table?.fields ?? []).map((f) => ({
89
    value: f.id,
90
    label: `${f.name} (${f.type})`,
91
  }))
92
}
93

94
/**
95
 * List Records
96
 * List the records of a table or of one of its views, with optional formula filter and sort. Follows Airtable's offset pagination to return every record (100 per page) up to max_records.
97
 */
98
export async function main(
99
  auth: RT.Airtable,
100
  base_id: DynSelect_base_id,
101
  table_id: DynSelect_table_id,
102
  view: DynSelect_view | undefined,
103
  filter_by_formula: string | undefined,
104
  sort_field: DynSelect_sort_field | undefined,
105
  sort_direction: "asc" | "desc" | undefined,
106
  max_records: number | undefined,
107
  return_fields_by_field_id: boolean | undefined
108
) {
109
  const records: any[] = []
110
  let offset: string | undefined = undefined
111

112
  do {
113
    const url = new URL(`https://api.airtable.com/v0/${base_id}/${table_id}`)
114
    if (view != null && view !== "") {
115
      url.searchParams.append("view", view)
116
    }
117
    if (filter_by_formula != null && filter_by_formula !== "") {
118
      url.searchParams.append("filterByFormula", filter_by_formula)
119
    }
120
    if (sort_field != null && sort_field !== "") {
121
      url.searchParams.append("sort[0][field]", sort_field)
122
      url.searchParams.append("sort[0][direction]", sort_direction || "asc")
123
    }
124
    if (max_records != null) {
125
      url.searchParams.append("maxRecords", String(max_records))
126
    }
127
    if (return_fields_by_field_id === true) {
128
      url.searchParams.append("returnFieldsByFieldId", "true")
129
    }
130
    if (offset) {
131
      url.searchParams.append("offset", offset)
132
    }
133

134
    const response = await fetch(url, {
135
      headers: {
136
        Authorization: `Bearer ${auth.apiKey}`,
137
        Accept: "application/json",
138
      },
139
    })
140
    if (!response.ok) {
141
      throw new Error(`${response.status} ${await response.text()}`)
142
    }
143

144
    const page = await response.json()
145
    records.push(...(page.records ?? []))
146
    offset = page.offset
147
  } while (offset)
148

149
  return { records }
150
}
151

Other submissions
  • Submitted by rossmccrann Deno
    Created 529 days ago
    1
    import { Airtable } from "https://deno.land/x/airtable/mod.ts";
    2
    
    
    3
    type Airtable = {
    4
      apiKey: string;
    5
    };
    6
    
    
    7
    type AirtableTable = {
    8
      baseId: string;
    9
      tableName: string;
    10
    };
    11
    export async function main(atCon: Airtable, atTable: AirtableTable) {
    12
      const airtable = new Airtable({ ...atCon, ...atTable });
    13
      const result_list = await airtable.select();
    14
    
    
    15
      return { results: result_list };
    16
    }
    17