Getting started with the Table data type

Table is a type of variable that stores an array of data (table rows). Each row is a separate element of an array. It is an object whose properties are defined by the table’s columns. Note that a table’s data is loaded along with the app item. This can make an app item’s view form load slower if the table placed on it has a large number of entries.

Get the number of rows in a table

As table rows are elements of an array, you can count the number of rows in a table using the TTable.length property that returns the amount of array elements as a number:

        // Assigning the amount of array elements (table rows) to a Number type variable
        Context.data.table_length = Context.data.table.length;

Get values from a table’s footer

To get the column total from a table, use the TTable.result property. You can only access the total in a column’s footer if it is configured in the table’s settings.

    // Making sure the footer in the column is filled out
    if (Context.data.table.result.cost) {

    // Assigning the total of the **Amount** column (**Money** type) to the variable. The type of the variable needs to correspond to the type of data in the column
        Context.data.order_budget = Context.data.table.result.cost;
    }

Get a row using its index

As a table is an array of data, you can access each element using square brackets []. This means that you can work with any row if you know its index. Note that the numbering of array elements starts with zero.

    /* Checking whether the number of the required row is entered and whether the table is long enough
       to get this row */
    if (Context.data.table && Context.data.table.length <= Context.data.rows_number) {

    /* Let’s use the row’s index to assign the required row to a variable.
       Numbering of array elements starts with zero, so we need to subtract one */
        const row = Context.data.table![Context.data.rows_number - 1];
    }

Delete a table row

The TTable.delete method deletes a row from a table.

// Getting an order
const order = await Context.data.orders!.fetch();

// Iterating through each row
for (let i = order.data.content!.length - 1; i >= 0; i--) {
    const row = order.data.content![i];

 // Checking whether the Number of units field is filled out
    if(!row.amount) {
        // Deleting the row if it is empty
        order.data.content!.delete(i);
    }
}
// Saving the order
await order.save();

Editing data in each row using a loop

Using the for loop, you can change the values of each element in an array.

Let’s add the currency to the cells storing the total amount by item (data type selected in the Amount column is String).

    // Checking whether the table is filled out
    if (Context.data.table && Context.data.table.length > 0) {

    /* Adding the currency to each row
       of the Amount column (String type) */
    for (let row of Context.data.table){
        row.cost = row.cost + ' dollars';
    }

    // Updating the table if the script runs on the client side
        Context.data.table = Context.data.table;
    }

This script will change the value of each row if the table has already been saved, that is, on a view form of an app item or on a task form if the table is passed from the app context to the business process context via the Assign Value activity.

Sort data in a table

To sort data in a table, use the sort() method. It sorts values in a column, writes the sorted values to an array, and returns the values to the original table, deleting unsorted rows.

    // Making sure the table is not empty
    if (Context.data.result_table.length > 0) {

    // Passing the table to a variable
        const table = Context.data.result_table;

    /* Creating a new array that repeats the structure of the table.
        The `map()` method creates a new array with the result of calling the specified function (f => f)
        for each array element */
        let sortTable = table.map(f => f);

    /* Let’s sort data in the array in the ascending order.
        Sorting will be based on the `number` property.
        We’ll use the native method `sort()`. */
        sortTable.sort((a, b) => a.number - b.number);

    /* Deleting items of the original table and
        creating a loop that iterates through each array element (table row).

        (let i = table.length - 1) returns the number of rows.
        We need to subtract one, as the numbering of array elements starts with zero.
        (i >= 0) is the condition upon which the loop will iterate.
        (i--) allows iterating over each element */
        for (let i = table.length - 1; i >= 0; i--) {

    // Deleting each row
            table.delete(i);
        };

        for (let i of sortTable) {

    /* Inserting sorted rows into the array created in the previous step.
       Inserting sorted values by columns (number, name) */
            const row = table!.insert();
            row.number = i.number;
            row.name = i.name;
        }
    }
\t// Re-initializing the table if the script runs on the client side
    Context.data.result_table = Context.data.result_table;

Get a row’s number from the row object

The TTable.indexOf method returns the first index an element can be found in an array or -1 if there is no such index.

    // Making sure the table and the value needed to find the row’s index are not empty
    if (Context.data.table.length > 0 && Context.data.row_value) {

    /* The number of the row that stores the needed value is returned.
        The numbering of array elements starts with 0, so we need to add one */
        Context.data.row_number = Context.data.table.indexOf(row) + 1;

    }

Filter data in a table

The TTable.filter method creates a new array with all elements that meet the condition set in the function that is passed. This method calls the passed callback function once for each element in the array. Then it creates a new array with all items for which the callback function returned a truthy value.

The callback function is called only for array indexes with values that are already defined. It cannot be called for indexes that have been deleted or haven’t been assigned values. Array elements that didn’t meet the filter condition set by the callback function are skipped. They are not included in the new array.

    // Making sure the table is not empty
    if (Context.data.table.length > 0) {

    // Passing the filtered table array to a variable
        let tab = Context.data.table.filter(i => i.name === Context.data.filter);

    // Clearing the original table
        if (Context.data.table.length > 0) {
        for (let i = Context.data.table.length - 1; i >= 0; i--) {
        Context.data.table.delete(i);
        }
    // Writing the filtered array of rows to the cleared table
        for (let j = 0; j <= tab.length - 1; j++) {
        let newRow = Context.data.table.insert();
        newRow.name = tab[j].name;
        newRow.cost = tab[j].cost;
        }

    /* Re-initializing the table (this in only needed if the script is on a form,
       and it is run on the client side) */
         Context.data.table = Context.data.table;
        }
    }

Find the first array element

The TTable.find method finds the first array element that meets the condition that’s passed.

    // Making sure the table is not empty
    if (Context.data.table.length > 0) {

    // Passing the first row in the table that meets the filter condition to a variable
        let tab = Context.data.table.find(i => i.name === Context.data.filter);
    }

Create an array with a function’s result

The TTable.map method creates a new array with the results of a specified function called for each array element.

    // Making sure the table is not empty
    if (Context.data.result_table.length > 0) {

    /* Passing the data array from the **Goods** (**App** type) column
    to an App type variable storing multiple values */
        Context.data.items = Context.data.result_table.map(f => f.product);
    }

One more example of using the TTable.map method can be found in the Sort data in a table section.

Insert a row into a table

To insert a new row into a table, pass the table to a variable and call the TTable.insert method. Then match the columns.

// Inserting a row; `row` is assigned a link to the new row
const row = order.data.table!.insert();

// Adding data to the row
row.item = Context.data.product!;
row.amount = Context.data.amount!;

Update a table

When a script modifying a table runs on the client side, you may need to update data in the table. To do that, you need to re-initialize it by assigning it to itself. You can see other examples of this in different scripts in the previous sections.

Context.data.table = Context.data.table;