doo.table
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): UseIDooGetBaseOption
to pass optional context likeapplicationId
.
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 likeapplicationId
orlongAttachmentToken
(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): OptionalIDooCrudOptions
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 infields
.
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): UseIDooGetBaseOption
to specifyapplicationId
orlongAttachmentToken
.
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 withid
andfields
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 withid
and fullfields
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
orgetFileArrayBuffer
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 IDdata.header
: Table namedata.items
: List of fields (withname
,header
,type
)data.settings
: Other table settingsdata.scripts
: Attached scripts (withname
andscript
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
- In this example, we load all orders with the status "Tentative" for a specific customer.
- 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.
- Then we increase the ordered amount in every order again, but we update only the field "Amount", not other fields (partial update).
- Then we insert a new order for a specific customer.
- 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).