Table

The Table object represents a table in your NocoDB base. Its methods let you get, query, and change the records in that table.

Overview

You usually get Table objects through the base object. Table objects are the primary way to:

  • Query records using various filters and conditions
  • Create, update, and delete records
  • Access and modify table fields and views
  • Perform bulk operations on table data

Properties

PropertyTypeDescription
idstringThe unique identifier of the table
namestringThe name of the table
descriptionstring | nullThe description of the table (if any)
fieldsField[]Array of user-defined fields in the table (no system fields)
viewsView[]Array of all views defined for the table
baseBaseReference to the parent base that this table belongs to

Methods

getField

Gets a field from the table by its ID or name. This method searches user-defined fields and system fields.

Parameters:

  • idOrName (string): The ID or name of the field to retrieve

Returns:

  • Field object if a match is found
  • null if no field matches the provided input

Note: The fields property includes only user-defined fields. getField() can get user fields and system fields (for example Created Time, Last Modified Time, etc.)

Example:

// Get a field by name
const titleField = projectsTable.getField('Title');

// Get a field by ID
const statusField = projectsTable.getField('c12345');

// Check if a field exists
if (titleField) {
  output.text(`Field "${titleField.name}" found with type: ${titleField.type}`);
} else {
  output.text('Field not found.');
}

getView

Gets a view from the table by its ID or name.

Parameters:

  • idOrName (string): The ID or name of the view to retrieve

Returns:

  • View object if a match is found
  • null if no view matches the provided input

Example:

// Get a view by name
const activeProjectsView = projectsTable.getView('Active Projects');

// Get a view by ID
const completedTasksView = projectsTable.getView('viw12345');

// Check if a view exists
if (activeProjectsView) {
  output.text(`View "${activeProjectsView.name}" found with type: ${activeProjectsView.type}`);
} else {
  output.text('View not found.');
}

selectRecordsAsync

Queries records from the table. Filtering and sorting are optional.

Parameters:

  • options (optional): Object with the following properties:
    • fields (Array<Field | string>): Specific fields to include in the result. If you do not specify fields, the result includes all fields.
    • sorts (Array<{field: Field | string, direction: 'asc' | 'desc'}>): Sorting options
    • recordIds (Array<string>): Specific record IDs to retrieve
    • pageSize (number): Maximum number of records to return per page (default: 50)
    • page (number): Page number for pagination (default: 1)
    • where (string): A where filter condition.

Returns: Promise<RecordQueryResult>: A promise that resolves to a RecordQueryResult object with pagination support

Example:

// Query records with options
const queryResult = await tasksTable.selectRecordsAsync({
  fields: ['Task Name', 'Status', 'Due Date'],
  sorts: [
    {field: 'Due Date', direction: 'asc'},
    {field: 'Status', direction: 'desc'}
  ],
  pageSize: 100
});

output.text(`Retrieved ${queryResult.records.length} records.`);

// Process the records
for (const record of queryResult.records) {
  const taskName = record.getCellValue('Task Name');
  const status = record.getCellValue('Status');
  output.text(`- ${taskName}: ${status}`);
}

// Check if there are more records
if (queryResult.hasMoreRecords) {
  // Load the next page of records
  const nextPage = await queryResult.loadMoreRecords();
  output.text(`Loaded ${nextPage.records.length} more records.`);
}

selectRecordAsync

Gets one record from the table by its ID.

Parameters:

  • recordId (string): The ID of the record to retrieve
  • options (optional): Object with the following properties:
    • fields (Array<Field | string>): Specific fields to include in the result

Returns: Promise<Record | null>: A promise that resolves to the Record object if a match is found

Example:

// Get a specific record by ID
const recordId = '123';
const record = await contactsTable.selectRecordAsync(recordId, {
  fields: ['Name', 'Email', 'Phone']
});

if (record) {
  output.text(`Contact: ${record.getCellValue('Name')}`);
  output.text(`Email: ${record.getCellValue('Email')}`);
  output.text(`Phone: ${record.getCellValue('Phone')}`);
} else {
  output.text(`Record with ID ${recordId} not found.`);
}

createRecordAsync

Creates a new record in the table with the specified field values.

Parameters:

  • data (Object): An object that maps field names or IDs to their values.

Returns: Promise<string>: A promise that resolves to the ID of the created record

Example:

// Create a new record
const newRecordId = await contactsTable.createRecordAsync({
  'Name': 'John Doe',
  'Email': 'john.doe@example.com',
  'Phone': '(555) 123-4567',
  'Status': 'Active'
});

output.text(`New record created with ID: ${newRecordId}`);

// Create a record with field IDs
const newRecordId2 = await contactsTable.createRecordAsync({
  'c123456': 'Jane Smith',  // Name field
  'c456789': 'jane@example.com'  // Email field
});

createRecordsAsync

Creates multiple records in the table.

Parameters:

  • data (Array<{fields: Object}>): An array of objects. Each object has a fields property that maps field names or IDs to their values.

Note: createRecordAsync takes a flat object. Here, each entry must put its values in fields. NocoDB ignores values outside fields and creates blank records.

Limit: You may create up to 10 records in one call.

Returns: Promise<Array<string>>: A promise that resolves to an array of IDs of the created records

Example:

// Create multiple records at once
const newRecordIds = await contactsTable.createRecordsAsync([
  { fields: {
    'Name': 'John Doe',
    'Email': 'john.doe@example.com',
    'Status': 'Active'
  }},
  { fields: {
    'Name': 'Jane Smith',
    'Email': 'jane.smith@example.com',
    'Status': 'Pending'
  }},
  { fields: {
    'Name': 'Bob Johnson',
    'Email': 'bob.johnson@example.com',
    'Status': 'Active'
  }}
]);

output.text(`Created ${newRecordIds.length} new records.`);

updateRecordAsync

Updates a record with the specified field values.

Parameters:

  • recordId (string | NocoDBRecord): The ID of the record to update or a NocoDBRecord object
  • data (Object): An object that maps field names or IDs to their new values.

Returns: Promise<void>: A promise that resolves when the update is complete

Example:

// Update a record by ID
await contactsTable.updateRecordAsync('123', {
  'Status': 'Inactive',
  'Last Contact Date': new Date().toISOString()
});

// Update a record using a Record object
const record = await contactsTable.selectRecordAsync('123');
if (record) {
  await contactsTable.updateRecordAsync(record, {
    'Notes': 'Customer requested follow-up next quarter.'
  });
  output.text('Record updated successfully.');
}

updateRecordsAsync

Updates multiple records with the specified field values.

Parameters:

  • records (Array<{id: string | NocoDBRecord, fields: Object}>): An array of objects. Each object has a record ID (or a NocoDBRecord object) and the field values to update.

Limit: You may update up to 10 records in one call.

Returns: Promise<void>: A promise that resolves when all updates are complete

Example:

// Update multiple records at once
await contactsTable.updateRecordsAsync([
  {
    id: '123',
    fields: {
      'Status': 'Active',
      'Last Contact Date': new Date().toISOString()
    }
  },
  {
    id: 'rec67890',
    fields: {
      'Status': 'Inactive',
      'Notes': 'Customer no longer interested.'
    }
  }
]);

output.text('Records updated successfully.');

deleteRecordAsync

Deletes a record from the table.

Parameters:

  • recordIdOrRecord (string | NocoDBRecord): The ID of the record to delete or a NocoDBRecord object

Returns: Promise<boolean>: A promise that resolves to true when the deletion is complete

Example:

// Delete a record by ID
await tasksTable.deleteRecordAsync('123');
output.text('Record deleted successfully.');

// Delete a record using a Record object
const record = await tasksTable.selectRecordAsync('678');
if (record) {
  await tasksTable.deleteRecordAsync(record);
  output.text(`Record "${record.name}" deleted successfully.`);
}

deleteRecordsAsync

Deletes multiple records from the table.

Parameters:

  • recordIds (Array<string>): Array of record IDs to delete

Limit: You may delete up to 10 records in one call.

Returns: Promise<boolean>: A promise that resolves to true when all deletions are complete

Example:

// Delete multiple records by ID
await tasksTable.deleteRecordsAsync(['123', '678', '246']);
output.text('Records deleted successfully.');

// Delete records using a query result
const completedTasks = await tasksTable.selectRecordsAsync({
  fields: ['Status'],
  where: '(Status, eq, Completed)',
});

const recordsToDelete = completedTasks.records.map(record => record.id);

// deleteRecordsAsync accepts at most 10 records per call
for (let i = 0; i < recordsToDelete.length; i += 10) {
  await tasksTable.deleteRecordsAsync(recordsToDelete.slice(i, i + 10));
}
output.text(`Deleted ${recordsToDelete.length} completed tasks.`);

createFieldAsync

Creates a new field in the table with the specified configuration.

Parameters:

  • field (Object): Field configuration object with:
    • name (string): Name for the new field
    • type (UITypes): Type of field to create
    • description (string, optional): Description for the field
    • options (Object, optional): Type-specific options for the field

Returns: Promise<Field>: A promise that resolves to the created Field object

Example:

// Create a new field
const ratingField = await projectsTable.createFieldAsync({
  name: 'Priority',
  type: UITypes.Rating,
  description: 'Project priority from 1-5',
  options: {
    icon: 'star',
    max_value: 5,
    color: '#FFCC00'
  }
});

output.text(`Created new field: ${ratingField.name}`);

// Create a select field
const statusField = await tasksTable.createFieldAsync({
  name: 'Status',
  type: UITypes.SingleSelect,
  options: {
    choices: [
      { title: 'Not Started', color: '#808080' },
      { title: 'In Progress', color: '#3366FF' },
      { title: 'Review', color: '#FF9900' },
      { title: 'Completed', color: '#33CC33' }
    ]
  }
});

Examples

Querying and Filtering Records

// Get the "Tasks" table
const tasksTable = base.getTable('Tasks');

// Get all tasks
const allTasks = await tasksTable.selectRecordsAsync();
output.text(`Total tasks: ${allTasks.records.length}`);

// Use a view to get filtered records
const inProgressView = tasksTable.getView('In Progress Tasks');
if (inProgressView) {
  const inProgressTasks = await inProgressView.selectRecordsAsync();
  output.text(`In-progress tasks: ${inProgressTasks.records.length}`);
}

// Get specific fields and sort by due date
const upcomingTasks = await tasksTable.selectRecordsAsync({
  fields: ['Task Name', 'Due Date', 'Status', 'Assigned To'],
  sorts: [
    { field: 'Due Date', direction: 'asc' }
  ],
  pageSize: 10
});

// Display the upcoming tasks
output.markdown('# Upcoming Tasks');
for (const task of upcomingTasks.records) {
  const name = task.getCellValue('Task Name');
  const dueDate = task.getCellValue('Due Date');
  const status = task.getCellValue('Status');
  const assignee = task.getCellValue('Assigned To');
  
  const assigneeName = assignee ? assignee.name : 'Unassigned';
  
  output.text(`- ${name} (${status}) due on ${dueDate} - Assigned to: ${assigneeName}`);
}

Creating and Updating Records

// Get the "Projects" table
const projectsTable = base.getTable('Projects');

// Create a new project
const newProjectId = await projectsTable.createRecordAsync({
  'Project Name': 'Website Redesign',
  'Start Date': new Date().toISOString(),
  'Status': 'Planning',
  'Budget': 15000,
  'Description': 'Complete overhaul of company website.'
});

output.text(`Created new project with ID: ${newProjectId}`);

// Retrieve the created project
const newProject = await projectsTable.selectRecordAsync(newProjectId);
if (newProject) {
  output.text(`New project: ${newProject.getCellValue('Project Name')}`);
  
  // Update the project after creation
  await projectsTable.updateRecordAsync(newProjectId, {
    'Project Lead': session.currentUser.id,
    'Team Size': 5
  });
  
  output.text('Project updated with lead and team size.');
}

// Create multiple tasks for the project
const tasksTable = base.getTable('Tasks');
const tasks = [
  { fields: {
    'Task Name': 'Requirements Gathering',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
  }},
  { fields: {
    'Task Name': 'Wireframes',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString()
  }},
  { fields: {
    'Task Name': 'Design Mockups',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 21 * 24 * 60 * 60 * 1000).toISOString()
  }}
];

const taskIds = await tasksTable.createRecordsAsync(tasks);
output.text(`Created ${taskIds.length} tasks for the project.`);

Bulk Processing with Pagination

// Get the "Contacts" table
const contactsTable = base.getTable('Contacts');

// Function to process all records with pagination
async function processAllRecords() {
  let queryResult = await contactsTable.selectRecordsAsync({
    fields: ['Name', 'Email', 'Last Contact Date'],
    pageSize: 100 // Process in batches of 100
  });
  
  let processedCount = 0;
  let updatedCount = 0;

  while (queryResult.hasMoreRecords) {
    await queryResult.loadMoreRecords();
  }
  
  // Process first batch
  let recordsToUpdate = [];
  for (const record of queryResult.records) {
    processedCount++;
    
    const lastContactDate = record.getCellValue('Last Contact Date');
    // If no contact in the last 90 days, mark for update
    if (!lastContactDate || new Date(lastContactDate) < new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)) {
      recordsToUpdate.push({
        id: record.id,
        fields: {
          'Status': 'Needs Follow-up',
          'Notes': 'No contact in the last 90 days.'
        }
      });
    }
  }
  
  // updateRecordsAsync accepts at most 10 records per call, so send in chunks
  for (let i = 0; i < recordsToUpdate.length; i += 10) {
    const chunk = recordsToUpdate.slice(i, i + 10);
    await contactsTable.updateRecordsAsync(chunk);
    updatedCount += chunk.length;
  }
  
  output.text(`Processing complete! Processed ${processedCount} total records, updated ${updatedCount}.`);
}

// Run the process
await processAllRecords();

Best Practices

  1. Batch operations: To create or update many records, use the bulk methods (createRecordsAsync, updateRecordsAsync), not individual calls. This gives better performance. Each call accepts at most 10 records, so split larger sets into chunks of 10.

  2. Paginate large queries: For large tables, use pagination with the pageSize option and the loadMoreRecords() method. This prevents memory issues.

  3. Error handling: Always put async operations in try/catch blocks to handle errors gracefully.

  4. Optimize field selection: Use the fields option in queries to request only the fields that you need. This improves performance.

Last updated on

Latest product updates?See Changelog
Stay in the loop? Follow us onLinkedInLinkedInYouTubeYouTubeXX