﻿# Batch operations with app items in scripts

> [HTML Version](batch-actions.html)

In BRIX, you can add and delete items, as well as update their fields in batches using batch methods in [scripts](type-script.md) written in the [TypeScript](https://www.typescriptlang.org/) language. This allows you to reduce the load on the system and the impact of set limits when you need to process a large amount of data. For example, if you have an integration set up with a third-party system, you can import a product catalog into the app from that system.

You can set the following methods in scripts:

- \[OBJECT\] to add app items in batches.

- \[OBJECT\] to update fields of app items in batches.

- \[OBJECT\] to delete app items in batches.

When writing scripts with methods for batch actions, please note the following conditions: 

- No more than 10 000 items are processed per request. This limitation applies to all the specified methods.

- To perform a batch action with items using a method, the user must have [permissions to import data from this app](360007527512.md#assign). This requirement applies to both client-side and server-side scripts.

In this article, we will look at examples of how to use methods in scripts. You can find more details in [BRIX TS SDK](https://tssdk.brix365.com/en/latest/pages/quick-start/intro_batch.html).

## Method for adding app items in batches

With \[OBJECT\], you can process a batch of app items in a single request. 

Use this method to:

- Save new items to the app.

- Update the fields of existing items. In this case, specify their identifiers so that you can use them to find the required items, make changes to them, and save the edited items in the database.

### Use case for adding items in batches

Let’s assume that a company uses the BRIX system, and marketing employees also work with a third-party service that stores product publications and customer comments.

You can import information from this external service to BRIX in bulk allowing employees from related departments to view all data in one place. For this:

1. Create apps for uploading publications and comments.

2. Set up integration via [a custom module](extentions.md) and add two script buttons to the module interface:

- **Add Posts **to import all publications from a third-party service to BRIX.

- **Add Comments** to upload all comments to these publications.

### Step 1: Create two apps

First, create [apps](360007235031.md) to import data into them. As you do so, add properties to the apps to match the fields of the publications and comments in the third-party system. Here is an example:  

- **Posts**. Contains the following properties:

	- **Name** (\[OBJECT\]). A system property, created automatically in BRIX.

	- **Number** (\[OBJECT\]). [The Number (integer) type](360009707032.md#number) for the identification number, by which the external system determines the link between the publication and its comments, i.e. the values of this field are equal in related items.

	- **Creation date** (\[OBJECT\]). [The Date/Time type](360009707032.md#date-time) to store the date of post creation.

	- **Title** (\[OBJECT\]). [The String (string) type](360009707032.md#string) for the title of the publication.

	- **Text** (\[OBJECT\]). The **String (text)** type for the text of the publication.

	- **Comments **\[OBJECT\]. [The App (one) type](360009707032.md#app) for a link to a related comment.

- **Comments**. Contains the following properties:

	- **Name** (\[OBJECT\]). A system property created automatically in BRIX.

	- **Number** (\[OBJECT\]). The **Number (integer)** type for the identification number by which the external system determines the link between the publication and its comments, i.e. the values of this field are equal in the related items.

	- **Creation date** (\[OBJECT\]). The **Date/Time** type to store the date of comment creation.

	- **User's e-mail** (\[OBJECT\]). The **Email address** type for the email of the user who left the comment.

	- **Message** (\[OBJECT\]). The **String (text)** type for the text of the comment.

	- **Posts **\[OBJECT\]**.** The **App (one)** type for the link to the linked post.

These properties will be used in the script to define the fields where the values sent from the external service will be written. Read more about filling in the **Comments** and **Posts** fields of the **App (one)** type in [Use case for updating item fields in batches](#use-case-2).

### Step 2: Configure data loading via a script

After creating the app, configure data import from the external system.

Here is how:

1. In the configured integration module, go to the [Settings](extention-settings.md) tab and click **Edit Form**.

2. In the interface designer that opens:

- Create the **Add Posts** and **Add Comments** buttons.

- On the **Scripts** tab, write Client-side code using \[OBJECT\]. This code will import data into the app when the user clicks the **Add Posts** or **Add Comments** buttons.

Code example

````
/\* Client scripts module \*/  
declare const console: any;  
/\*  
//Asynchronous function to import comments from the external service  
async function import\_comments(): Promise<void> \{  
//Request the external service to get comments  
    const result = await fetch('https://externalservicewebsite.com/comments');  
//Convert the response to JSON format  
    const comments = await result.json();  
//Initialize an array for storing comment items  
    const items: any = \[\];  
//Check each comment in the received list  
    for (let c of comments) \{  
//Create a new comment item in the app  
        const item = Context.fields.commentapp.app.create();  
//Fill in the fields of the comment item  
        item.data.\_\_name = c.name;  
        item.data.email = \[\{ \{ type: EmailType.Home, email: c.email \}\];  
        item.data.body = c.body;  
        item.data.postID = c.postId;   
        items.push(item);  
    \}  
//Save all created comment items in a batch  
    await Context.fields.commentapp.app.batch().save().items(items).all();  
\}  
//Asynchronous function to import posts from the external service  
async function import\_posts(): Promise<void> \{  
//Request the external service to get posts  
    const result = await fetch('https:// externalservicewebsite.com/posts');  
//Convert the response into JSON format  
    const posts = await result.json();  
//Initialize an array for storing post items  
    const items: any = \[\];  
//Check each post in the received list  
    for (let p of posts) \{  
//Create a new post item in the app  
        const item = Context.fields.postsapp.app.create();  
//Fill in the fields of the post item  
        item.data.\_\_name = p.title;  
        item.data.body = p.body;   
        item.data.postID = p.id;  
        items.push(item);  
    \}  
//Batch save all created post items  
    await Context.fields.postsapp.app.batch().save().items(items).all();  
\}
````

3. ````
Save and publish the changes.

The buttons will then appear in the [settings](extention-settings.md#settings) of the integration module. The user can now click them to add new items to the **Posts** and **Comments** apps.

## Method for updating item fields in batches

To update multiple item fields in a single request, use the \[OBJECT\] method in the script. This allows you to:

- Specify the rules for such an update.

- Define search criteria for items to be updated.

- Limit the number of items to be updated.

### Use case for updating fields in batches

In [Use case for adding items in batches](#use-case-1), we transferred data from the external system to the **Posts** and **Comments** apps using the \[OBJECT\] method in the script. However, the **Posts** field in comment pages and **Comments** field in post pages are still empty. The links for these fields are not transferred from the external system, but are created in BRIX. 

Let's fill these empty fields with links to related items so that employees can quickly find the necessary information when working in these apps. 

To do this, we will use the \[OBJECT\] method to update the fields in bulk.  

In the third-party system, the link between publications and comments is defined through the **Number** (\[OBJECT\]) field. The value in this field is the same in all the linked items. We will use this property in the script to find the required publications and add links in the **Posts** field to comment pages.

To do this:

1. In the customized integration module, go to the [Settings](extention-settings.md) tab and click **Edit Form**.

2. In the interface designer that opens, add the [Button](button_widget.md) widget and name it **Update Links**.

3. On the **Scripts** tab, write the code that will update the links between the items of the **Posts** and **Comments** apps. When the user clicks the **Update Links** button, the links in the **Post** fields will be updated in the comment pages.

Sample code:

````
//Asynchronous function to update the Posts field in comments  
Async function update\_comments(): Promise<void> \{  
//Search for and retrieve posts from the Posts application  
    const posts = await Context.fields.postsapp.app.search().size(100).from(0).all();  
    for (let p of posts) \{  
//Batch update the values in the Posts field in the comment pages by comparing the values in the Number (postID) field. If the values match, a link to the linked item is added to the Posts field.  
        await Context.fields.commentapp.app.batch().update().update().set(“post”, (f, op) => p).where((f) => f.postID.eq(p.data.postID ?? 0)).all();  
    \}  
\}
````

4. ````
Save and publish the changes.

After that, the **Update Links** button will appear in the [settings](extention-settings.md#settings) of the integration module. Now, users can click it to update the **Posts** field in the comment pages.

## Method for deleting items in batches

You can use the \[OBJECT\] method in the script to delete many app items in a single request. In doing so, you can:

- Define search criteria for the items to be deleted.

- Specify the number of items to be deleted.

### Use case for deleting items in batches 

In the previous use cases, we used a script [to add data from a third-party system](#use-case-1) to the **Posts** and **Comments** apps and [update the fields of their items](#use-case-2).

Now let's configure batch deletion of data using a script. We will add two buttons to the page of the third-party system integration module. When clicking them, the user will be able to delete outdated items of the **Posts** or **Comments** apps, for example, records that were created before 01.01.2024.

To do this:

1. In the integration module of the third-party system, go to the **Settings** tab and click the **Edit Form** button.

2. In the interface designer that opens, add the **Button** widget, set the **Delete Posts** name and the **Script** type.

3. Bind a batch deletion script to this button. Specify in it the criterion of searching for items and the number of records to be deleted in one request. When the script is executed, the number of such requests is determined automatically. In the use case, we will delete items created before 01.01.2024 in batches of 100 pieces.  
To do this, specify the \[OBJECT\] function name in the button settings on the **Main** tab in the **Executed script** field. Then click **Save** and **Open**.

4. On the **Scripts** tab that opens, add the following script:

````
// Asynchronous function to delete all items from the Posts app  
async function delete\_posts(): Promise<void> \{  
// specify a variable to track the number of items deleted   
    let rows = 0;  
// use a loop to delete all items  
    do \{  
        rows = await   
// Add a method for mass deletion of items in the Posts app and specify the criterion for selecting items and the number of records in one deletion request.     
Context.fields.postsapp.app.batch().delete().delete().where((f) => f.\_\_createdAt.lt(new Datetime('2024-01-01'))).size(100).from(0).all();  
    \}   
while (rows > 0)      
\}

5. ````
Now, we need to create another button to delete entries in the **Comments** app in a similar way. We will delete items according to the same criteria: depending on their creation date, 100 pieces at a time.  
To do this, add the **Button** widget on the **Template** tab.  Perform the same settings as for the **Delete Posts** button. When writing the script, use the code of the **Comments** app variable.

6. Save and publish the updates.

Now, the module settings will display buttons for deleting items from the **Posts** and **Comments** apps depending on their creation date.