View Metadata API

Is there any way to access the extension APIs outside of an airtable extension? The view metadata provided by the extensions resources Airtable Blocks SDK includes visible fields and other view metadata that the public view metadata API does not have Airtable Web API

1 Like

Welcome to the Airtable community!

In general, no, it is not possible to use the features of one SDK in a different SDK/API.

2 Likes

I recently logged a feature enhancement request for this very limitation - the ability to return an array of visible fields within specified views. It’s frustrating not to have this feature - the only alternative is to hardcode your own visible field object into scripts - not ideal.

1 Like

Yeah, would save us a ton of time in manual auditing processes if we could pull what fields are visible in a view and which table(s) a view/share is syncing to. I built a quick little extension to export the visible field mapping as a csv that I’ve included below, used this combined with a python script to semi-automatically update this information in an ecosystem map we have. But it’s still an awkward solution compared to the script I have which pulls all the other information and it doesn’t even work on some tables with a large number of fields and views because the extension runs out of memory (yes, I know it could be refactored to map fields to views to solve for this but it already takes forever and I can’t be bothered)

import {initializeBlock, FormField, Button} from '@airtable/blocks/ui';
import {base} from '@airtable/blocks';
import React, { useState } from 'react';

function Main() {
	const [specifiedTable, setSpecifiedTable] = useState("")
    const generateCSV = async () => {
		let res = ""
		if (specifiedTable === "") {
			for (const table of base.tables) {
				console.log(table.name)
				for (const view of table.views) {
					let x = view.selectMetadata()
					await x.loadDataAsync()
					res += `${view.id},${x.visibleFields.map(field => field.id).toString()}\n`
					await x.unloadData()
				}
			}
		} else {
			for (const table of base.tables) {
				if (table.name === specifiedTable) {
					for (const view of table.views) {
						let x = view.selectMetadata()
						await x.loadDataAsync()
						res += `${view.id},${x.visibleFields.map(field => field.id).toString()}\n`
						await x.unloadData()
					}
				}
			}
		}

		// Once the csv string is generated, download it for the user
		const element = document.createElement("a")
		const file = new Blob([res], {type: 'text/plain'})
		element.href = URL.createObjectURL(file)
		element.download = `${base.name} - ${new Date().toISOString()}.csv`
		document.body.appendChild(element) // Required for this to work in FireFox
		element.click()
	}
    return (
	<div>
		<FormField htmlFor="table" label="Table">
			<input 
				placeholder="" 
				id="table" 
				name="table"
				value={specifiedTable} 
				onChange={(e) => setSpecifiedTable(e.target.value)}
			/>
		</FormField>
		<Button onClick = {() => {generateCSV()}}>Generate View Mapping CSV</Button>
	</div>)
}
initializeBlock(() => <Main />)

One idea that I’ve had is to take a sample record that’s listed within a desired view - and then to parse all null / undefined fields that could potentially mark those fields as hidden within my script. After all, if there’s no data in them, then why not class them as hidden for that particular routine?

I’ll execute this idea over the weekend, see if it has any legs. Makes sense in my head, but not sure how it’ll go in the real world.

Regardless, I’m really hoping Airtable update their Script api to return an array of visible fields per view object.

Yeah you can do it this way by creating a dummy record with only the views visible fields filled, but that would all have to be managed manually per view and I have thousands of views so no dice here.