doo.table

How to manipulate data in tables in Tabidoo scripts.

The doo.table object in Tabidoo provides a comprehensive set of functions to interact with your table data programmatically via TypeScript (JavaScript). Whether you're creating, updating, or deleting records, filtering data, or working with attachments, doo.table gives you full control using the same rights as a logged-in user.

Key Concepts

  • doo.table methods can be run both in client-side scripts (on model load, on model change, before model save) and in scripts for Workflow Automation.
  • Not allowed in: Calculated fields, data load conditions in roles, or conditions for using a whole role.

Using these functions and filters is very similar to using the Tabidoo API.    
You can learn more about Tabidoo API documentation here: https://tabidoo.docs.apiary.io

Using Generics in doo.table Methods

You can use doo.table methods in two ways:

Without Generics: Use general form when data types are not strictly needed.

const result = await doo.table.getData('Orders');

With Generics: Type-safe access using auto-generated interfaces based on your table definitions.

const result = await doo.table.getData<IDooApiTableMyTable>('Orders');

Each table in your Tabidoo application automatically has an associated interface like IDooApiTableMyTable, containing all fields and their types, including links, dates, files, and booleans.

Using generics enhances code readability, autocomplete, and reduces runtime errors.

Data Retrieval

Functions to load, count, or summarize data:

doo.table.getData()

getData loads a list of records from the specified table. You can apply filters, sorting, pagination, and define which fields to load.

Syntax

const result = await doo.table.getData<T>(tableNameOrId, options?, applicationId?);
// or
const result = await doo.table.getData(tableNameOrId, options?, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • options (optional): Filtering, sorting, pagination settings.
  • applicationId (optional): Use to load data from a different application.

Returns: An object with a data array containing matching records.

Example: Load Data Using Generics

Load all records from the Orders table (with strong typing and autocomplete support).

const result = await doo.table.getData<IDooApiTableOrders>('Orders');
const firstOrder = result.data[0];
console.log(firstOrder.fields.amount);

Example: Filtered and Sorted Data

Retrieve the most recent 10 orders with status 'New'.

const result = await doo.table.getData<IDooApiTableOrders>('Orders', {
	filter: 'status(eq)New',
	sort: 'created(desc)',
	limit: 10
});

Example: Load Specific Fields Only

Improve performance by loading only selected fields (status and amount).

const result = await doo.table.getData<IDooApiTableOrders>('Orders', {
 	loadFields: ['status', 'amount']
});

Notes

  • You must use await as this function is asynchronous.
  • Maximum record count is limited by limit parameter (default: 25).
  • Use the generated TypeScript interface for safer access to fields.

doo.table.getCount()

getCount returns the number of records in a table that match the specified filter. It’s useful when you want to know how many records meet certain conditions without loading the full data.

Syntax

const result = await doo.table.getCount(tableNameOrId, options?, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • options (optional): Filtering conditions.
  • applicationId (optional): Use to load data from a different application.

Returns: An object of type IDooGetCountResponse with nested data.count: number

Example: Count All Records

Get the total number of orders in the Orders table.

const result = await doo.table.getCount('Orders');
console.log(result.data.count);

Example: Count Records with Filter

Count how many orders have the status 'New'.

const result = await doo.table.getCount('Orders', {
  filter: 'status(eq)New'
});
console.log(result.data.count);

Notes

  • If no filter is provided, all records are counted.
  • Always use await as this is an async method.
  • Efficient for summaries or validations without data transfer overhead.

doo.table.getDataSummary()

getDataSummary returns aggregated values (like sum, average, min, max) from numeric or date/datetime fields. Useful for reporting and dashboards.

Syntax

const result = await doo.table.getDataSummary<T>(tableNameOrId, options, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • options (optional): Object specifying filters and aggregation setup.
  • applicationId (optional): For querying another app.

Returns: An object of type IDooGetDataSummaryResponse<T>, with a data.fields object containing aggregation results per field.

Example: Summary of Orders Amount

Calculate total, average, and range of amounts for all orders.

const summary = await doo.table.getDataSummary<IDooApiTableOrdersSummary>('Orders', {
  fields: {
    amount: { aggregations: ["sum", "avg", "min", "max"] }
  }
});
console.log(summary.data.fields.amount.sum);

Example: Summary with Filters

Get stats only for orders placed this year.

const summary = await doo.table.getDataSummary<IDooApiTableOrdersSummary>('Orders', {
  filter: [{ field: 'created', operator: 'gte', value: '2025-01-01' }],
  fields: {
    amount: { aggregations: ["avg"] },
    created: { aggregations: ["min", "max"] }
  }
});
console.log(summary.data.fields.amount.avg);
console.log(summary.data.fields.created.min);

Notes

  • Aggregations min/max/sum/avg are supported for numeric fields.
  • Aggregations min/max are supported for date or datetime fields.
  • The generic interface IDooApiTableXYZSummary defines which fields and aggregations to expect.
  • Only number and date/datetime fields are supported.
  • Use await to ensure the operation completes.
  • Results are grouped under result.data.fields by field name.
  • Filter format matches that of getData.

doo.table.getParameter()

getParameter is used to retrieve the value of a single-parameter record stored in a special table (like Application Parameters). Useful for configuration, constants, and settings.

Syntax

const value = await doo.table.getParameter<T>(tableNameOrId, fieldName, options?);

Parameters

  • tableNameOrId: The name or ID of the parameter table.
  • fieldName: The name of the field to retrieve.
  • options (optional): Use IDooGetBaseOption to pass optional context like applicationId.

Returns: A value of type T (e.g. string).

Example: Load Default Currency

Assume the Application Parameters table contains a field defaultCurrency.

const currency = await doo.table.getParameter<string>('App Params', 'defaultCurrency');
console.log(currency);

Example: Load Boolean Setting

Load a toggle or flag used in business logic.

const isFeatureEnabled = await doo.table.getParameter<boolean>('Settings', 'enableBeta');
if (isFeatureEnabled) {
	// do something
}

Use cases

  • Centralized configuration management.
  • Dynamic values like thresholds, toggles, labels.
  • Read app-specific settings via scripting.

Notes

  • Works best with tables that have exactly one record (Application Parameters).
  • Returns the field value directly, not wrapped in data.fields.

Record Operations

Functions to create, update, or delete single records:

doo.table.getRecord()

getRecord loads a single record by its ID from the specified table. Returns full record metadata including id, created, modified, and all field values.

Syntax

const result = await doo.table.getRecord<T>(tableNameOrId, recordId, options?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • recordId: The ID of the record to retrieve.
  • options (optional): Optional configuration options like applicationId or longAttachmentToken (IDooGetBaseOption).

Returns: An object of type IDooGetRecordResponse<T>, where data.fields contains your record's data.

Example: Load a Customer Record

Load specific customer details by ID.

const result = await doo.table.getRecord<IDooApiTableCustomers>('Customers', 'a8098c1a-f86e-11da-bd17-00112444be1e');
console.log(result.data.fields.firstname);

Example: Load Using Linked Record ID

Load customer data where the ID comes from another record (e.g. selected customer).

const result = await doo.table.getRecord<IDooApiTableCustomers>('Customers', doo.model.customer.value.id);
console.log(result.data.fields.firstname);

Notes

  • Always use await as this method is asynchronous.

doo.table.createRecord()

createRecord inserts a new record into the specified table. You provide a set of field values, and the response includes full record metadata and field content.

Syntax

const result = await doo.table.createRecord<T>(tableNameOrId, fields, options?);

Parameters

  • tableNameOrId: Name or ID of the target table.
  • fields: Object with field names and values.
  • options (optional): Optional IDooCrudOptions such as:
    • applicationId (optional): Target application (default: current app).
    • reloadUserDataAfterAction(optional): If user data should be refreshed (client-side only). (default: false)
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGetRecordResponse<T> containing metadata and fields with the record values.

Example: Create Customer Record

const result = await doo.table.createRecord<IDooApiTableCustomers>('Customers', {
  firstname: 'Alice',
  surname: 'Smith'
});
console.log(result.data.fields.firstname);

Use cases

  • Add a new record during workflow execution.
  • Automatically create related data.
  • Save form input programmatically.

Notes

  • Always await the method since it's asynchronous.
  • Returns full metadata (id, created, etc.) and user data in fields.

doo.table.updateFields()

updateFields performs a partial update on a record — only the specified fields will be changed. It's faster and safer than replacing the whole record.

Syntax

await doo.table.updateFields<T>(tableNameOrId, recordId, fields, options?);

Parameters

  • tableNameOrId: Name or ID of the target table.
  • recordId: The ID of the record to update.
  • fields: Object with only the fields you want to update.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • reloadUserDataAfterAction(optional): If user data should be refreshed (client-side only). (default: false)
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGetRecordResponse<T> with updated fields and metadata.

Example: Update Firstname Field Only

await doo.table.updateFields<IDooApiTableContacts>('Contacts', 'a8098c1a-f86e-11da-bd17-00112444be1e', {
  firstname: 'Jack'
});

Use cases

  • Update a single field from a form or script.
  • Optimize performance by avoiding full record overwrite.

Notes

  • Always await the method since it's asynchronous.

doo.table.updateRecord()

updateRecord updates a full record in the specified table by replacing all fields with new values. Use this when you want to overwrite the entire record, not just selected fields.

Syntax

const result = await doo.table.updateRecord<T>(tableNameOrId, recordId, fields, options?);

Parameters

  • tableNameOrId: Name or ID of the target table.
  • recordId: The ID of the record to update.
  • fields: Object containing all field values to overwrite the record.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • reloadUserDataAfterAction(optional): If user data should be refreshed (client-side only). (default: false)
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGetRecordResponse<T> with updated fields and record metadata.

Example: Replace All Fields of a Contact

const result = await doo.table.updateRecord<IDooApiTableContacts>('Contacts', 'a8098c1a-f86e-11da-bd17-00112444be1e', {
  firstname: 'Jack',
  surname: 'Smith',
  age: 35
});
console.log(result.data.fields.age);

Use cases

  • Replace the full content of a record.

Notes

  • All fields will be overwritten — missing fields will be erased.
  • Use doo.table.updateFields(...) instead if only partial changes are needed.
  • Always await the method since it's asynchronous.

doo.table.deleteRecord()

deleteRecord removes a specific record from the specified table based on its ID. This operation is irreversible and should be used with caution.

Syntax

await doo.table.deleteRecord(tableNameOrId, recordId, options?);

Parameters

  • tableNameOrId: Name or ID of the target table.
  • recordId: The ID of the record to be deleted.
  • fields: Object containing all field values to overwrite the record.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: Promise<void> – no data is returned on success.

Example: Delete Customer Record

await doo.table.deleteRecord('Customers', 'a8098c1a-f86e-11da-bd17-00112444be1e');

Use cases

  • Permanently remove outdated or incorrect records.
  • Clean up test or imported data.
  • Enable delete actions from UI or workflow scripts.

Notes

  • Cannot be undone. Make sure to confirm the action before calling.
  • Ensure proper permissions are set – not all roles may delete records.
  • Always await the method since it's asynchronous.

Linked Records

Functions for interacting with linked table data:

doo.table.getLinkedRecordsV2()

getLinkedRecordsV2 retrieves all related records from a linked table using a simplified signature. Ideal for loading 1:N relationships like invoice rows, sub-items, or communication logs.

Syntax

const result = await doo.table.getLinkedRecordsV2<T>(tableNameOrId, recordId, linkFieldName, options?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • recordId: The ID of the record you want to load linked records for.
  • linkFieldName: The name of the field that links to the main record.
  • options (optional): Use IDooGetBaseOption to specify applicationId or longAttachmentToken.

Returns: An object of type IDooGetDataResponse<T>, containing a data array with full metadata and fields.

Example: Load Invoice Rows

Get all items linked to a specific invoice header.

const rows = await doo.table.getLinkedRecordsV2<IDooApiTableInvoiceRows>('Invoice Header', doo.model.invoice.id, 'invoiceHeader');
console.log(rows.data.map(r => r.fields.itemName));

Notes

  • Replaces the older getLinkedRecords() with a cleaner signature.
  • Ensure the linkFieldName matches the link field in the related table.
  • Always use await as this method is asynchronous.

doo.table.getLinkedRecords()

getLinkedRecords retrieves all related records from a linked table using a more verbose syntax. This method is deprecated and has been replaced by getLinkedRecordsV2, which is more concise and easier to use.

Syntax

const result = await doo.table.getLinkedRecords<T>(tableNameOrId, recordId, linktableNameOrId, linkFieldName, options?);

Notes

  • This method is still functional but no longer recommended.
  • Use getLinkedRecordsV2 instead for cleaner and safer code.

Bulk Operations

Functions to handle multiple records at once:

doo.table.createRecordsBulk()

createRecordsBulk allows you to insert multiple records at once into a table. It’s ideal for importing or generating data in batches.

Syntax

const result = await doo.table.createRecordsBulk<T>(tableNameOrId, fieldsArray, options?);

Parameters

  • tableNameOrId: Target table name or ID.
  • fieldsArray: Array of objects, each containing the fields of one record.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGeneralBulkResponse<T> with:

  • bulk.successCount: Number of successful inserts.
  • data[]: Array of created records with metadata.
  • errors[]: Array of any errors encountered per record.

Example: Add Multiple Customers

const result = await doo.table.createRecordsBulk<IDooApiTableCustomers>('Customers', [
  { firstname: 'Alice', surname: 'Brown' },
  { firstname: 'Bob', surname: 'Smith' }
]);

console.log(`Inserted ${result.bulk.successCount} records`);

Use cases

  • Import records from external systems.
  • Add multiple entries from form input or logic.
  • Improve performance by minimizing repeated requests.

Notes

  • Each item in fieldsArray represents one new record.
  • Always await the method since it's asynchronous.

doo.table.updateRecordsBulk()

updateRecordsBulk updates multiple records in a single operation. Each record must include its ID and the fields to be updated. This method is useful for batch processing or applying changes to a dataset.

Syntax

const result = await doo.table.updateRecordsBulk<T>(tableNameOrId, bulkArray, options?);

Parameters

  • tableNameOrId: The target table name or ID.
  • bulkArray: An array of objects with id and fields for each record to update.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGeneralBulkResponse<T> with:

  • bulk.successCount: Number of successfully updated records.
  • data[]: Array of updated records.
  • errors[]: Array of any errors encountered per record.

Example: Bulk Update Contacts

const result = await doo.table.updateRecordsBulk<IDooApiTableContacts>('Contacts', [
  { id: 'a8098c1a-f86e-11da-bd17-00112444be1e', fields: { source: 'linkedin' } },
  { id: '550e8400-e29b-41d4-a716-446655440000', fields: { source: 'facebook' } }
]);
console.log(`Updated ${result.bulk.successCount} records.`);

Use cases

  • Mass update fields based on user input.
  • Automate repetitive changes.
  • Efficient syncing with external systems.

Notes

  • Fields are merged (partial update); missing fields are preserved.
  • Always provide the id for each record (if the id is empty or the record is not found in the table, the record is ignored/skipped without reporting).
  • Always await the method since it's asynchronous.

doo.table.updateFullRecordsBulk()

updateFullRecordsBulk replaces entire records in bulk. Each item must include the record id and all fields that define the record. This method is best used when performing full record replacement, e.g., from a backup or synchronization source.

Syntax

const result = await doo.table.updateFullRecordsBulk<T>(tableNameOrId, bulkArray, options?);

Parameters

  • tableNameOrId: The target table name or ID.
  • bulkArray: An array of objects with id and full fields per record.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • useUpsert (optional): Insert or update if already exists (default: false).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGeneralBulkResponse<T> with:

  • bulk.successCount: Number of successfully updated records.
  • data[]: Array of updated records.
  • errors[]: Array of any errors encountered per record.

Example: Replace Full Customer Records

const result = await doo.table.updateFullRecordsBulk<IDooApiTableCustomers>('Customers', [
  {
    id: 'a8098c1a-f86e-11da-bd17-00112444be1e',
    fields: {
      firstname: 'New Name',
      surname: 'New Surname'
    }
  },
  {
  	id: '550e8400-e29b-41d4-a716-446655440000',
    fields: {
      firstname: 'New Name',
      surname: 'New Surname'
    }
  }
]);

Use cases

  • Full overwrite from external systems.
  • Restore archived or backup data.
  • Synchronize complex state changes.

Notes

  • Entire record is replaced — missing fields will be cleared.
  • If only partial changes are needed, use updateRecordsBulk instead.
  • Always include id for each record.
  • Always await the method since it's asynchronous.

doo.table.deleteRecordsBulk()

deleteRecordsBulk removes multiple records from a table in one operation based on a filter. It’s ideal for batch deletions (e.g., archived records or cleanup routines). This operation is irreversible and should be used with caution.

Syntax

const result = await doo.table.deleteRecordsBulk<T>(tableNameOrId, limit, filter, options?);

Parameters

  • tableNameOrId: The target table name or ID.
  • limit: Maximum number of records to delete in this operation.
  • filter: String filter expression to select records for deletion.
  • options (optional): IDooCrudOptions including:
    • applicationId (optional): Target application (default: current app).
    • skipAudit (optional): Skip audit logging (default: false).

Returns: An object of type IDooGeneralBulkResponse<T> with:

  • bulk.successCount: Number of successfully updated records.
  • errors[]: Array of any errors encountered per record.

Example: Delete Archived Customers

const result = await doo.table.deleteRecordsBulk<IDooApiTableCustomers>('Customers', 100, 'status(eq)Archived');
console.log(`Deleted ${result.bulk.successCount} records`);

Use cases

  • Remove test data or cleanup after import.
  • Periodic deletion of inactive/archive entries.
  • Mass remove items after business logic completes.

Notes

  • Always combine with a filter to prevent accidental mass deletions.
  • Cannot be undone. Make sure to confirm the action before calling.
  • Use limit to control the batch size.
  • Requires appropriate user permissions.
  • Always await the method since it's asynchronous.

File Handling

Functions to work with file fields:

doo.table.getFile() (as text)

getFile retrieves the raw text content of a file uploaded to a record field. This is useful for reading .txt, .json, .xml and similar files encoded in UTF-8.

Syntax

const fileText = await doo.table.getFile(tableNameOrId, fileId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table containing the file.
  • fileId: The internal ID of the file (e.g. from a file field).
  • applicationId (optional): Use this to retrieve the file from another application.

Returns: A Promise<string> — the raw text content of the file.

Example: Read JSON File Content

const fileContent = await doo.table.getFile('Documents', 'file-id');
const json = JSON.parse(fileContent);
console.log(json);

Use cases

  • Read data from uploaded .json or .xml configuration files.
  • Extract plain text for processing or display.
  • Mass remove items after business logic completes.

Notes

  • Only works for UTF-8 encoded text files.
  • For binary content, use getFileBase64 or getFileArrayBuffer instead.

doo.table.getFileBase64()

getFileBase64 retrieves an uploaded file by its ID and returns its base64 representation. Useful for previewing or sending binary files like images or PDFs.

Syntax

const file = await doo.table.getFileBase64(tableNameOrId, fileId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table containing the file.
  • fileId: The internal ID of the file (e.g. from a file field).
  • applicationId (optional): Specify if the file belongs to another app.

Returns: A Promise<IDooGetFileBase64> with:

  • content: Base64 encoded content of the file.
  • fileName: The original file name.
  • mimeType: MIME type (e.g., 'image/png', 'application/pdf').
  • fileSize: File size in bytes.

doo.table.getFileArrayBuffer()

getFileArrayBuffer retrieves a file from a record and returns its raw binary content as an ArrayBuffer. This method is suitable for advanced binary processing such as working with files in JavaScript APIs (e.g. Blob, FileReader).

Syntax

const fileBuffer = await doo.table.getFileArrayBuffer(tableNameOrId, fileId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • fileId: The file’s internal ID.
  • applicationId (optional): Specify if the file belongs to another application.

Returns: A Promise<ArrayBuffer> — containing binary data of the file.

Example: Convert to Blob and Open

const buffer = await doo.table.getFileArrayBuffer('Invoices', 'file-id');
const blob = new Blob([buffer], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
window.open(url);

Use cases

  • Download and manipulate binary files.
  • Work with images, PDFs, and other media in browser APIs.
  • Prepare files for uploads to external services.

Notes

  • Ideal for non-text files (e.g., PDFs, images, spreadsheets).
  • Use await since this is an asynchronous function.

doo.table.getThumbnail()

getThumbnail loads a thumbnail image of a file stored in a record. It returns the binary image data as an ArrayBuffer.

Syntax

const thumbnail = await doo.table.getThumbnail(tableNameOrId, fileId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table containing the file.
  • fileId: The file’s internal ID.
  • applicationId (optional): Specify if the file belongs to another application.

Returns: A Promise<ArrayBuffer> — binary data of the thumbnail image.

Example: Display Thumbnail

const buffer = await doo.table.getThumbnail('Gallery', 'file-id');
const blob = new Blob([buffer], { type: 'image/png' });
const url = URL.createObjectURL(blob);
document.getElementById('preview').src = url;

Use cases

  • Display image previews in custom components.
  • Optimize performance when full-resolution image is not needed.
  • Use thumbnails in dashboards or summary lists.

Notes

  • Only supported for image-based file types.
  • Use await since this is an asynchronous function.

doo.table.getThumbnailBase64()

getThumbnailBase64 retrieves a thumbnail image of an uploaded file and returns its base64-encoded content along with metadata.

Syntax

const thumbnail = await doo.table.getThumbnailBase64(tableNameOrId, fileId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table containing the file.
  • fileId: The file’s internal ID.
  • applicationId (optional): Specify if the file belongs to another application.

Returns: A Promise<IDooGetFileBase64> with:

  • content: Base64 encoded thumbnail image.
  • fileName: Name of the file.
  • mimeType: MIME type of the thumbnail (e.g., image/jpeg).
  • fileSize: Size of the thumbnail in bytes.

Example: Show Thumbnail in Image Element

const thumb = await doo.table.getThumbnailBase64('Images', 'file-id');
document.getElementById('thumb').src = `data:${thumb.mimeType};base64,${thumb.content}`;

Use cases

  • Quickly render preview images.
  • Optimize performance when full-resolution image is not needed.

Notes

  • Only supported for image-based file types.
  • Use await since this is an asynchronous function.

Others

doo.table.getTableStructure()

getTableStructure loads the full structure of a table including field definitions, settings, and attached scripts. Useful for introspection, debugging, or dynamic UI generation.

Syntax

const structure = await doo.table.getTableStructure(tableNameOrId, applicationId?);

Parameters

  • tableNameOrId: The name or ID of the table.
  • applicationId (optional): Use to specify the application context.

Returns: An object of type IDooGetTableStructureResponse with data that includes structure, settings, and script definitions.

Example: Load Table Structure

const structure = await doo.table.getTableStructure('Customers');
console.log(structure.data.items.map(f => f.name));

Structure Format

  • data.id: Table ID
  • data.header: Table name
  • data.items: List of fields (with name, header, type)
  • data.settings: Other table settings
  • data.scripts: Attached scripts (with name and script content)

Use cases

  • Generate dynamic forms or filters based on field list.
  • Export table configurations.

Notes

  • Field types are returned as simple strings (e.g. 'text', 'number').
  • Requires appropriate permissions to access structure data.

doo.table.reloadUserData()

reloadUserData refreshes the data in all active views (grid, cards, calendar, widgets, linked subviews) for the given table(s). It ensures that changes are reflected immediately across the UI.

Syntax

doo.table.reloadUserData(tableNamesOrIds);

Parameters

  • tableNamesOrIds: A string or array of strings — table name(s) or ID(s) to reload.

Returns: void

Example: Reload a Table

doo.table.reloadUserData('Customers');

Example: Reload Multiple Tables

doo.table.reloadUserData(['Orders', 'Invoices']);

Use cases

  • After performing data changes from custom scripts.
  • When your logic affects linked tables, reports, or dashboards.
  • To force a UI refresh without reloading the whole page.

Notes

  • This function is automatically called after:
    • createRecord
    • updateFields
    • updateRecord
    • deleteRecord
    • createRecordsBulk
    • updateRecordsBulk
    • updateFullRecordsBulk
    • deleteRecordsBulk
  • Useful when manually updating other data that may affect current views.
     

You can learn more about these functions in Tabidoo API documentation here.

All functions except reloadUserData are asynchronous and you must use the await keyword to wait until they are finished and get a result or catch an error.


Common Parameters Explained

Explanation of the function parameters.

tableNameOrId

You can use the table name (header), internal table name for API, or table ID to determine which table you want to work with. When using a name (header) of the table, it is expected that exactly one table in the application has this name otherwise, an error is thrown. Alternatively, you can set and use an internal table name (unique within the application), or a table ID (you can see the ID in the URL in the browser's address bar when you use this table in Tabidoo).

applicationId

If this parameter is not provided (or it is null) then the ID of the current (opened) application is used (eg. app. ID where the edit form was opened). You can provide desired application ID when you want to load/save the data from/to a specific application (you must have sufficient user rights to load/save from/to this application). You can get the application ID from the URL (the address row in the browser) when you open desired application (eg. https://app.tabidoo.cloud/app/123-456/table/...).

recordId

Unique record identification (ID). The easiest way to get the record ID is to open the record form and click the share button - the URL containing the record ID will be displayed (look at the end of the URL). Example:

...?recordId=8ef96265-1e21-49db-909b-94a8f004aade

fields

Set of record fields. Example:

{
	"firstname": "Jack",
    "surname": "Newman"
}

options (GET)

Options parameter for getData, getCount and getLinkedRecordsV2 functions. 

Example - Simple filter

Find all records where the field surname contains the string "Fox" or "Dog" or "text with , comma".
To filter text containing a comma, such as "text with , comma", you must escape the comma inside the text by a double backslash.

{ 
	filter: "surname(in)(Fox,Dog,text with \\, comma)",  // data filter in simple string form *
	sort: "age,surname(desc)",       					 // data sort
	loadFields: [ 'code', 'description' ]				 // load only some columns
	limit: 25,                       					 // number of records to load (one page)
	skip: 3                          					 // number of pages to skip (default)
}
                

Example - Advanced filter

Find all records where field age equals 25 and field firstname equals Jack or Peter.

{
	filter: [
		{
			field: "age",
			operator: "eq",
			value: "25"
		},
		{
			filter: [
				{
					field: "firstname",
					operator: "eq",
					value: "Jack"
				},
				{
					field: "firstname",
					operator: "eq",
					value: "Peter"
				}
			],
    		filterOperator: "or"  // "and"/"or" operator for items in "filter" array on the same level
 		}
	],                            // data filter in advanced form (tree) *
	filterOperator: "and",        // "and"/"or" operator for items in "filter" array on the same level
	sort: "age,surname(desc)",    // data sort
	limit: 25,                    // number of records to load (one page)
	skip: 3                       // number of pages to skip (default)
}

Options parameter for getDataSummary functions. 
Only number and date/date-time fields are supported. 
Aggregations min/max/sum/avg are supported for numbers. 
Aggregations min/max are supported for date/date-time.

Example - Parameters for doo.table.getDataSummary

{
	"filter": [
    	{ 
        	"field": "age",
            "operator": "gte",
            "value": "30"
        }   
    ],
    "fields": {
    	"age": { aggregations: ["min", "max", "sum", "avg"] },
        "dateOfBirth": { aggregations: ["min", "max"] },
        "someNumber": { aggregations: ["avg"] },
        "dateOfEmployment": { aggregations: ["min"] }
    }
}

Example - Using the currently set user data filter in the current table

{
	"filter": doo.environment.currentApplication.currentTable.dataConditions,
    "fields": {
    	"age": { aggregations: ["avg"] }
    }
}

options (CREATE, UPDATE, DELETE)

Options parameter for createRecord, updateFields, updateRecord, deleteRecord, createRecordsBulk, updateRecordsBulk, updateFullRecordsBulk, deleteRecordsBulk functions. 

It contains these optional parameters: applicationId?, reloadUserDataAfterAction?,  useUpsert?, dataResponseType?.

Example - Using the options parameter:

{
	applicationId: 'My App',			// application 'My App'
	reloadUserDataAfterAction: false,	// user data is not loaded
	useUpsert: true,					// allow upsert mode
    skipAudit: true,                    // allows skip or force audit, otherwise table settings is used
	dataResponseType: 'MetadataOnly'	// use 'MetadataOnly' response type
}

fieldsArray

Parameter for createRecordsBulk function. Each set of fields represents a new record. 

Example - Create two records (Jack Newman and Peter Novak):

[
	{
		"firstname": "Jack",
		"surname": "Newman"
	},
	{
		"firstname": "Peter",
		"surname": "Novak"
	}
]

bulkArray

Parameter for updateRecordsBulk and updateFullRecordsBulk function.

Example - Update two records:

[
    {
      "id": "158cb6ef-02a6-47dc-8134-188c1b6426e6",
      "fields": {
        "firstname": "Jack",
        "surname": "Newman"
      }
    },
    {
      "id": "2f64141a-ec9f-43df-a50d-1ca8eb277df7",
      "fields": {
        "firstname": "Peter",
        "surname": "Novak"
      }
    }
]

fileId

Unique file identification (ID). Parameter for getFile and getThumbnail functions. 

fieldName

The name of the field in the table.

reloadUserDataAfterAction

User data is loaded (true) or not loaded (false) in all displayed data views (grid/tabs/calendar/...) that are currently displayed to the user (main table, widgets, linked tables on the open edit form, ...). The default value is true.

useUpsert

Tabidoo API and doo.table CREATE/UPDATE functions (including bulk functions) support two upsert modes:

  • The CREATE functions (createRecord, createRecordsBulk) enable UPSERT mode - UPSERT for CREATE functions is driven by the 'Import key field' (one field of the table marked as 'Import key field' in the table/fields settings - unique record identifier for data import) - the passed-in record has to have non-empty value in the field marked as 'Import key field' then this value is used for search for the record in the DB, if the record exists then it is updated, if the record does not exist then a new record is created (inserted). If the passed-in record has no value in the field marked as 'Import key field' then CREATE UPSERT raises an error.
     
  • The UPDATE functions (updateFields, updateRecord, updateRecordsBulk, updateFullRecordsBulk) enable UPSERT mode - UPSERT for UPDATE functions is driven by record ID - if the passed-in record has no id or the record is not found in the DB by id then a new record is created (inserted), otherwise found record is updated.

The default value is false.

skipAudit

Option of whether or not the data change will be reflected in the audit.

Check Data audit limitation chapter for details here.

dataResponseType

The response body of the CREATE and UPDATE functions contains a newly created or updated record. You can change the default settings by changing that parameter.

  • "All" - the response body contains all fields of the record (default for simple Create and Update functions, not allowed for bulk functions).
  • "MetadataOnly" - only metadata is returned in the response body (record ID(s), created/modified time, ...).
  • "None" - no data is returned in the response body (default for bulk operations).

 

filter

You can filter user data by simple filtering conditions. You can learn more about filters in Tabidoo API documentation here.

Example - Usage of the simple filter: Find all records where the field surname equals the string "Newman".

"surname(eq)Newman"  // simple filter       

It does not support advanced API filters.


Common Return values

 

Example - Return value for getData, getLinkedRecordsV2 and getLinkedRecords functions.

{
	"data": [
		{
			"id": "158cb6ef-02a6-47dc-8134-188c1b6426e6",
			"created": "2019-03-22T14:41:23.5783244+00:00",
			"modified": "2019-03-24T16:31:28.5783244+00:00",
			"ver": 0,
			"fields": {
				"firstname": "John",
				"surname": "Snow",
				"age": 35
			}
		},
		{
			"id": "8905f3aa-97df-4c0b-b10f-d5fe3bcd6979",
			"created": "2019-03-22T14:41:23.5783244+00:00",
			"modified": "2019-03-24T16:31:28.5783244+00:00",
			"ver": 2,
			"fields": {
				"firstname": "Jack",
				"surname": "Reacher",
				"age": 42
			}
		}
	]
}
                

Example - Return value for getCount function.

{
	"data": {
		"count": 3
	}
}       

Example - Return value for getDataSummary function.

{ 
	"data": {
    	"count": 3,
        "fields": {
        	"age": {
            	"min": 31,
                "max": 44,
                "sum": 111,
                "avg": 37,
            },
            "dateOfBirth": {
            	"min": "1980-05-23T00:00:00Z",
                "max": "1994-07-03T00:00:00Z",
            },
            "someNumber": {
            	"avg": 24
            },
            "dateOfEmployment": {
            	"avg": "2002-11-11T12:34:56Z"
            }
        }
    }
}    

Example - Return value for getRecord, createRecord, updateFields and updateRecord functions.

{
	"data": {
		"id": "158cb6ef-02a6-47dc-8134-188c1b6426e6",
		"created": "2019-03-22T14:41:23.5783244+00:00",
		"modified": "2019-03-24T16:31:28.5783244+00:00",
		"ver": 0,
		"fields": {
			"firstname": "John",
			"surname": "Snow",
			"age": 35
		}
	}
}             

Example - Return value for createRecordsBulk, updateRecordsBulk and updateFullRecordsBulk functions.
This example shows that three records were sent for bulk update, two recorde were updated and one record was not updated (it was unchanged or it does not exist).
In UPSERT mode, some records can be inserted and some can be updated.
 

{
	"bulk": {
		"successCount": 3,
		"insertedCount": 0,
		"updatedCount": 2
	},
	"data": [
		{
			"id": "158cb6ef-02a6-47dc-8134-188c1b6426e6",
			"created": "2019-03-22T14:41:23.5783244+00:00",
			"modified": "2019-03-25T17:22:26.5783244+00:00",
			"ver": 0,
			"fields": {
				"firstname": "Jack",
				"surname": "Newman"
			}
		},
		{
			"id": "2f64141a-ec9f-43df-a50d-1ca8eb277df7",
			"created": "2019-03-22T14:41:23.5783244+00:00",
			"modified": "2019-03-25T17:22:26.5783244+00:00",
			"ver": 0,
			"fields": {
				"firstname": "Peter",
				"surname": "Novak"
			}
		}
	],
	"errors": [
		{
			"type": "string",
			"id": "string",
			"message": "string"
 		}
	]
}
                

Handle Errors

Functions may fail due to missing or incorrectly filled-in parameters - eg incorrectly/incompletely filled-in data filter, text passed to a parameter of type number, a table was not found by name, etc. When editing javascript in Tabidoo Javascript editor you can see errors under the JS editor or in the browser's developer's console (F12).    
You can also catch the error using the try-catch clause:

try {
	// correct filter syntax: { filter: 'myitem(eq)5' } - internal field name, (eq) operator
	const cnt = await doo.table.getCount('My table', { filter: 'My item = 5' });
} catch(err) {
	console.log(err);
}

Caught err object:    

{
	"errorData": {
		"errors": [
			{
				"type": "warning",
				"id": "parameterParseFailedException",
				"message": "'filter' parameter parse failed - filter condition 'my item = 5' has a bad format - operator not found.",
				"RecordIndex": 0
			}
		]
	}
}

You can learn more about API errors in Tabidoo API documentation here.


Debugging tips

In case, you are not sure, how the model object looks like or what the value of a variable is, check the value in the developer console of the browser.

console.log(doo.model);

Or you can debug your JavaScript step by step and check values of variables and so on in the developer console of the browser using the debugger command in your code (be sure to delete it when done :))

debugger;

You can open the developer console by pressing F12 in Chrome/Edge browser or CTRL+SHIFT+I in Opera browser and similarly in other browsers.


Example

  1. In this example, we load all orders with the status "Tentative" for a specific customer.
  2. Then we set the status to "Approved" and we increase the ordered amount in every order and then we update (save) all whole records (all fields) in the DB.
  3. Then we increase the ordered amount in every order again, but we update only the field "Amount", not other fields (partial update).
  4. Then we insert a new order for a specific customer.
  5. Then we delete the oldest order with the status "Canceled" for a specific customer - only when the number of Canceled orders is greater than 10.

 

// 1. In this example, we load all orders with the status "Tentative" for a specific customer.
const orders = await doo.table.getData('My Orders', { 
	filter: 'Customer(eq)john@smith.com,Status(eq)Tentative' 
});
// 2. Then we set the status to "Approved" and we increase the ordered amount in every order and then we update (save) all whole records (all fields) in the DB.
for(const order of orders.data) {
	order.fields.Status = 'Approved';
	order.fields.Amount += 1.5;
}
for(const order of orders.data) {
	const updatedRecord = await doo.table.updateRecord('My Orders', order.id, order.fields);
}
// 3. Then we increase the ordered amount in every order again, but we update only the field "Amount", not other fields (partial update).
for(const order of orders.data) {
	const updatedRecord = await doo.table.updateFields('My Orders', order.id, {
		Amount: order.fields.Amount + 2.7
	});
}
// 4. Then we insert a new order for a specific customer.
const insertedOrder = await doo.table.createRecord('My Orders', {
	Customer: 'john@smith.com',
	Date: new Date(),
	Status: 'New',
	Amount: 30
});
// 5. Then we delete the oldest order with the status "Canceled" for a specific customer - only when the number of Canceled orders is greater than 10.
const count = await doo.table.getCount('My Orders', { 
	filter: 'Customer(eq)john@smith.com,Status(eq)Canceled' 
});
if (count.data.count > 10) {
	const ordersForDelete = await doo.table.getData('My Orders', { 
		filter: 'Customer(eq)john@smith.com,Status(eq)Canceled',
		sort: 'Date',
		limit: 1
	});
	if (ordersForDelete.data.length) {
		await doo.table.deleteRecord('My Orders', ordersForDelete.data[0].id);
	}
}
                

In this example, the table name "My Orders" is used instead of the "My Orders" table ID. Exactly one table in this application is expected to be named "My Orders".    
Alternatively, you can set and use an internal table name, or you can use a table ID (you can see the ID in the browser's developer tools when you load data from this table in Tabidoo).

Was this article helpful?