Search code examples
javascriptairtable

Listing records with Airtable API


I have an Airtable base that I can retrieve records from (see code below), but I'd like to get the value for other fields besides just "Location". Using "console.log('Retrieved: ', record.get('Location'));", how do I modify this line to include in the output the field values for a field called "Size" in addition to the "Location" field? I tried "console.log('Retrieved: ', record.get('Location', 'Size'));", but that didn't work.

Here's an excerpt from my code:

// Lists 3 records in Bins 
base('Bins').select({
    // Selecting the first 3 records in Grid view:
    maxRecords: 3,
    view: "Grid view"
}).eachPage(function page(records, fetchNextPage) {
    // This function (`page`) will get called for each page of records.

    records.forEach(function(record) {
        console.log('Retrieved: ', record.get('Location'));
    });

    // To fetch the next page of records, call `fetchNextPage`.
    // If there are more records, `page` will get called again.
    // If there are no more records, `done` will get called.
    fetchNextPage();

}, function done(err) {
    if (err) { console.error(err); return; }
});

OUTPUT

Retrieved 170000118

Retrieved 170000119

Retrieved 170000120


Solution

  • I found this repo to help in when I tried to product situations like this. A wrapper for common functions for accessing data on an airtable.com database. All queries return promises.

    Here is how it works if you want to avoid using an npm package. But ultimatly the jist of it is to either use request or some short of promise fulfillment menthod to retrive the Records.

    import Airtable from 'airtable'
    import _ from 'lodash'
    
    const ENDPOINT_URL = 'https://api.airtable.com'
    let API_KEY // Can only set the API key once per program
    
    export default class AirTable {
    
        constructor({apiKey, databaseRef}) {
            if(!API_KEY) {
                API_KEY = apiKey
                Airtable.configure({
                    endpointUrl: ENDPOINT_URL,
                    apiKey: API_KEY
                });
            }
            this.base = Airtable.base(databaseRef)
            this.get = {
                single: this.getSingleRecordFrom.bind(this),
                all: this.getAllRecordsFrom.bind(this),
                match: this.getAllMatchedRecordsFrom.bind(this),
                select: this.getRecordsSelect.bind(this)
            }
            this.insert = this.createRecord.bind(this)
            this.add = this.insert
            this.create = this.insert
    
            this.update = this.updateRecord.bind(this)
            this.set = this.update
    
            this.remove = this.deleteRecord.bind(this)
            this.delete = this.remove
            this.destroy = this.remove
            this.rem = this.remove
        }
    
        async createRecord({tableName, data}) {
            return new Promise((resolve, reject) => {
                this.base(tableName).create(data, (err, record) => {
                    if (err) {
                        console.error(err)
                        reject()
                        return
                    }
                    console.log("Created " + record.getId())
                    resolve(record)
                })
            })
        }
    
        async updateRecord({tableName, id, data}) {
            return new Promise((resolve, reject) => {
                this.base(tableName).update(id, data, (err, record) => {
                    if (err) {
                        console.error(err)
                        reject()
                        return
                    }
                    console.log("Updated " + record.getId())
                    resolve(record)
                })
            })
        }
    
        async deleteRecord({tableName, id, data}) {
            return new Promise((resolve, reject) => {
                this.base(tableName).destroy(id, (err, record) => {
                    if (err) {
                        console.error(err)
                        reject()
                        return
                    }
                    console.log("Deleted " + record.getId())
                    resolve(record)
                })
            })
        }
    
        async getSingleRecordFrom({tableName, id}) {
            console.log(tableName, id)
            return new Promise((resolve, reject) => {
                this.base(tableName).find(id, function(err, record) {
                if (err) {
                    console.error(err)
                    reject(err)
                }
                resolve(record)
                })
                    // console.log(record);
            })
        }
    
        async getAllRecordsFrom(tableName) {
            return this.getRecordsSelect({tableName, select: {} })
        }
    
        async getAllMatchedRecordsFrom({tableName, column, value}) {
            return this.getRecordsSelect({tableName, select: {filterByFormula:`${column} = ${value}`} }) // TODO: validate input
        }
    
        async getRecordsSelect({tableName, select}) {
            return new Promise((resolve, reject) => {
                let out = []
                this.base(tableName).select(select).eachPage((records, fetchNextPage) => {
                    // Flatten single entry arrays, need to remove this hacky shit.
                    _.map(records, r => {
                        _.forOwn(r.fields, (value, key) => { // If array is single
                            if(_.isArray(value) && value.length == 1 && key != 'rooms') {
                                r.fields[key] = value[0]
                            }
                        });
                    })
                    out = _.concat(out, records)
                    fetchNextPage();
                }, (err) => {
                    if (err) {
                        console.error(err)
                        reject(err)
                    } else {
                        // console.log(JSON.stringify(out, null, 4))
                        // console.log("HI")
                        resolve(out)
                    }
                })
            })
        }
    }
    

    Hope this Makes sense, Also trying to make an API-Proxy fetching a whole table or even use Express to fetch record id's as arrays can work as well