# View

> Part of the NocoDB documentation (Workflows > Scripts > API Reference). Index of all pages: https://nocodb.com/llms.txt. Any docs page is available as Markdown by adding `.md` to its URL.

URL: https://nocodb.com/docs/workflows/scripts/api-reference/view
Last updated: 2026-10-03

The View object in NocoDB Scripts represents a view of a table and lets you query its records.

The `View` object represents a view of a table in your NocoDB base. A view shows your table data with filters, sorts, and other customizations.

## Overview

Use views in NocoDB to:

* Apply filters to show only specific records from a table
* Define custom sorting for records
* Show or hide specific fields

In NocoDB Scripts, use View objects to work with these filtered subsets of data. You do not have to write the filtering logic in your script.

## Properties

| Property      | Type             | Description                                                                     |
| ------------- | ---------------- | ------------------------------------------------------------------------------- |
| `id`          | `string`         | The unique identifier of the view                                               |
| `name`        | `string`         | The name of the view                                                            |
| `description` | `string \| null` | The description of the view (if any)                                            |
| `type`        | `string`         | The type of view (for example, 'grid', 'form', 'gallery', 'kanban', 'calendar') |
| `table`       | `Table`          | Reference to the parent table that this view belongs to                         |

## Methods

### selectRecordsAsync

Queries records from the view. Optional parameters set the fields, the sorting, and the pagination.

**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. It adds to the existing view filters

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

**Example:**

```javascript
// Get the Projects table and Active Projects view
const projectsTable = base.getTable('Projects');
const activeProjectsView = projectsTable.getView('Active Projects');

// Query records from the view
const queryResult = await activeProjectsView.selectRecordsAsync({
  fields: ['Project Name', 'Status', 'Deadline', 'Assigned To'],
  sorts: [
    { field: 'Deadline', direction: 'asc' }
  ],
  pageSize: 50
});

while(queryResult.hasMoreRecords) {
  await queryResult.loadMoreRecords()
}

output.text(`Found ${queryResult.records.length} active projects.`);

// Process the records
for (const record of queryResult.records) {
  const projectName = record.getCellValue('Project Name');
  const deadline = record.getCellValue('Deadline');
  const assignedTo = record.getCellValue('Assigned To');
  
  const assigneeName = assignedTo ? assignedTo.name : 'Unassigned';
  
  output.text(`- ${projectName} due on ${deadline} - Assigned to: ${assigneeName}`);
}
```

### selectRecordAsync

Gets one record from the view by its ID. The view's filters and permissions apply.

**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. The result always includes the primary key and primary value fields.

**Returns:** `Promise<NocoDBRecord | null>`: A promise that resolves to the NocoDBRecord object. It resolves to null if the record is not found, if the view filters it out, or if an AxiosError occurs

**Example:**

```javascript
// Get a specific record through a view
const tasksTable = base.getTable('Tasks');
const myTasksView = tasksTable.getView('My Tasks');

const recordId = '123';
const task = await myTasksView.selectRecordAsync(recordId, {
  fields: ['Task Name', 'Status', 'Due Date', 'Notes']
});

if (task) {
  output.text(`Task: ${task.getCellValue('Task Name')}`);
  output.text(`Status: ${task.getCellValue('Status')}`);
  output.text(`Due Date: ${task.getCellValue('Due Date')}`);
  output.text(`Notes: ${task.getCellValue('Notes')}`);
} else {
  output.text(`Record with ID ${recordId} not found in this view.`);
  // Note: The record might exist in the table but be filtered out by the view
}
```

## Using Views for Filtering

A primary benefit of views is filtering. Use a view to filter data, and do not write complex filtering logic in your scripts.

```javascript
// Example: Processing overdue tasks
const tasksTable = base.getTable('Tasks');
const overdueTasksView = tasksTable.getView('Overdue Tasks');

// This view already has filters for tasks where Due Date < Today and Status != Completed
const overdueTasks = await overdueTasksView.selectRecordsAsync({
  fields: ['Task Name', 'Due Date', 'Assigned To', 'Status']
});

while(overdueTasks.hasMoreRecords) {
  await overdueTasks.loadMoreRecords()
}

// Create a notification summary
output.markdown('# Overdue Tasks Summary');
output.text(`There are ${overdueTasks.records.length} overdue tasks.`);

// Group tasks by assignee
const tasksByAssignee = {} as Record<string, {
  name: string,
  tasks: Array<{name: string, dueDate: string}>
}>;
for (const task of overdueTasks.records) {
  const assignee = task.getCellValue('Assigned To');
  const assigneeId = assignee ? assignee.id : 'unassigned';
  const assigneeName = assignee ? assignee.name : 'Unassigned';
  
  if (!tasksByAssignee[assigneeId]) {
    tasksByAssignee[assigneeId] = {
      name: assigneeName,
      tasks: []
    };
  }
  
  tasksByAssignee[assigneeId].tasks.push({
    name: task.getCellValue('Task Name'),
    dueDate: task.getCellValue('Due Date')
  });
}

// Output summary by assignee
for (const [assigneeId, assigneeData] of Object.entries(tasksByAssignee)) {
  output.markdown(`## ${assigneeData.name}`);
  for (const task of assigneeData.tasks) {
    const daysOverdue = Math.floor((new Date() - new Date(task.dueDate)) / (1000 * 60 * 60 * 24));
    output.text(`- ${task.name} (${daysOverdue} days overdue)`);
  }
}
```

## Creating Interactive Reports Using Views

Use views to create interactive reports for different data segments.

```javascript
// Let the user choose a view from the Sales table
const salesTable = base.getTable('Sales');
const viewOptions = salesTable.views.map(view => view.name);

const selectedViewName = await input.selectAsync(
  'Select a sales report view to analyze:',
  viewOptions
);

const selectedView = salesTable.getView(selectedViewName);
const sales = await selectedView.selectRecordsAsync({
  fields: ['Date', 'Amount', 'Product', 'Sales Rep', 'Region']
});

while(sales.hasMoreRecords) {
  await sales.loadMoreRecords()
}

// Calculate summary statistics
let totalSales = 0;
const salesByRep = {};
const salesByProduct = {};
const salesByRegion = {};

for (const record of sales.records) {
  const amount = record.getCellValue('Amount') || 0;
  const rep = record.getCellValue('Sales Rep');
  const product = record.getCellValue('Product');
  const region = record.getCellValue('Region');
  
  totalSales += amount;
  
  // Sales by rep
  if (rep) {
    const repName = rep.name;
    if (!salesByRep[repName]) {
      salesByRep[repName] = 0;
    }
    salesByRep[repName] += amount;
  }
  
  // Sales by product
  if (product) {
    if (!salesByProduct[product]) {
      salesByProduct[product] = 0;
    }
    salesByProduct[product] += amount;
  }
  
  // Sales by region
  if (region) {
    if (!salesByRegion[region]) {
      salesByRegion[region] = 0;
    }
    salesByRegion[region] += amount;
  }
}

// Output the report
output.markdown(`# Sales Report: ${selectedViewName}`);
output.text(`Total Sales: $${totalSales.toFixed(2)}`);
output.text(`Number of Transactions: ${sales.records.length}`);
output.text(`Average Transaction: $${(totalSales / sales.records.length).toFixed(2)}`);

// Display sales by rep
output.markdown('## Sales by Representative');
const salesByRepData = Object.entries(salesByRep)
  .map(([rep, amount]) => ({ Rep: rep, Amount: amount }))
  .sort((a, b) => b.Amount - a.Amount);
output.table(salesByRepData);

// Display sales by product
output.markdown('## Sales by Product');
const salesByProductData = Object.entries(salesByProduct)
  .map(([product, amount]) => ({ Product: product, Amount: amount }))
  .sort((a, b) => b.Amount - a.Amount);
output.table(salesByProductData);

// Display sales by region
output.markdown('## Sales by Region');
const salesByRegionData = Object.entries(salesByRegion)
  .map(([region, amount]) => ({ Region: region, Amount: amount }))
  .sort((a, b) => b.Amount - a.Amount);
output.table(salesByRegionData);
```

## Best Practices

1. **Use views for filtering**: Use views to apply complex filters. Do not write filtering logic in your script.

2. **Remember views are read-only**: View objects can only query records. You create and update records at the table level.

3. **Combine with Table operations**: Use views to read and filter data. Use table methods to write data.

4. **Await async operations**: Always use `await` when you call async methods. This makes sure that the code runs in the correct order.

## Related

* [Base](/docs/workflows/scripts/api-reference/base)
* [Table](/docs/workflows/scripts/api-reference/table)
* [Record](/docs/workflows/scripts/api-reference/record)
* [RecordQueryResult](/docs/workflows/scripts/api-reference/record-query-result)

---

## Related pages

- [Base](https://nocodb.com/docs/workflows/scripts/api-reference/base.md): The base object in NocoDB Scripts gives access to the tables and collaborators of the current base.
- [Cursor](https://nocodb.com/docs/workflows/scripts/api-reference/cursor.md): The cursor object in NocoDB Scripts tells a script which base, table, view and row are active.
- [Table](https://nocodb.com/docs/workflows/scripts/api-reference/table.md): The Table object in NocoDB Scripts represents a table and gives methods to query, create, update, and delete its records.
- [Field](https://nocodb.com/docs/workflows/scripts/api-reference/field.md): The Field object in NocoDB Scripts gives access to the configuration of a table column, and the field types and their cell values.
- [RecordQueryResult](https://nocodb.com/docs/workflows/scripts/api-reference/record-query-result.md): The RecordQueryResult object in NocoDB Scripts holds the records from a query and supports pagination.
- [Record](https://nocodb.com/docs/workflows/scripts/api-reference/record.md): The NocoDBRecord object in NocoDB Scripts represents one table row and gives methods to read its cell values.
- [Session](https://nocodb.com/docs/workflows/scripts/api-reference/session.md): The session object in NocoDB Scripts gives information about the user who runs the script.
- [Collaborator](https://nocodb.com/docs/workflows/scripts/api-reference/collaborator.md): The Collaborator object in NocoDB Scripts holds the ID, name and email of a user who has access to a base.
