Velo Repeaters: The Lifecycle of Repeated Items

Visit the Velo by Wix website to onboard and continue learning.

When working with a repeater using code, it is important to understand how the items in the repeater are created, updated, and deleted. But first, you need to understand the relationship in a repeater between its repeated items and its data. 

A repeater's data is stored as an array of objects. You get and set that array using the repeater's data property. Each object in the array must contain a unique _id property which is used to match the object's data to the individual repeated items of the repeater as described below. The value of the _id property can only be comprised of alphanumeric characters and hyphens (-). Other than _id, the objects in the repeater's data array can contain anything you want.

For example, a simple array of repeater data may look like this:

Copy
1
[
2
{
3
"_id": "1",
4
"firstName": "John",
5
"lastName": "Doe",
6
"image": "http://someImageUrl/john.jpg"
7
},
8
{
9
"_id": "2",
10
"firstName": "Jane",
11
"lastName": "Doe",
12
"image": "http://someImageUrl/jane.jpg"
13
}
14
]

Repeater data is not automatically applied to the elements in the repeated items. You choose how to use the repeater's data in the onItemReady(), onItemRemoved(), forItems(), and forEachItem() callback functions. Most often, you will be applying the data of a repeated item to the properties and functions of the repeated elements contained in that repeated item.

For more information on these functions, see the API Reference.

Creating New Items

When you set a repeater's data property, new repeated items are created for each object that has an _id value that is not already present in the current array of data objects. The elements in the new items are first populated with the data of the repeater's item template. Then the onItemReady() event handler is triggered for each of the new items. Usually, you will overwrite some or all of the data populated from the item template in the onItemReady() event handler with the data for that specific item. When all of the onItemReady() event handlers have finished running, the new items are displayed.

For example, if the repeater's data property currently contains the following array:

Copy
1
[{"_id": "1", "content": "First"}]

And then you set its value to this array:

Copy
1
[{"_id": "1", "content": "First"},{"_id": "2", "content": "Second"}]

One new repeated item is created because an item with ID "2" did not yet exist. The onItemReady() event handler will run once for the new item. There you can set up its contents.

Updating Existing Items

When you set a repeater's data property, nothing occurs to repeated items whose IDs were already in the array of data objects, even if other data in the object has changed. To update repeated items with the new data, use the forEachItem() or forItems() functions.

For example, if the repeater's data property currently contains the following array:

Copy
1
[{"_id": "1", "content": "First"}]

And then you set its value to this array:

Copy
1
[{"_id": "1", "content": "New First"}]

The content of elements in the exisitng repeated item will not change because an item with ID "1" already exists. To update the contents you need to call either the forEachItem() or forItems() functions.

Removing Items

When you set a repeater's data property, repeated items are removed if their IDs are no longer in the array of data objects. The onItemRemoved() event handler is triggered for each of the removed items.

For example, if the repeater's data property currently contains the following array:

Copy
1
[{"_id": "1", "content": "First"},{"_id": "2", "content": "Second"}]

And then you set its value to this array:

Copy
1
[{"_id": "1", "content": "First"}]

One repeated item is removed because an item with ID "2" no longer exists. The onItemRemoved() event handler will run once for the removed item.

Example

To demonstrate the full lifecycle of repeated items, we will use the following simplified example. 

The example has the following page elements:

  • Three buttons:
    • The Add button adds more items to the repeater.
    • The Remove button removes the added items from the repeater.
    • The Update button updates the first item in the repeater.
  • A repeater where each repeated item in the repeater contains two text elements:
    • The text element on the left shows the item's ID.
    • The text element on the right shows the item's content.

The example has the code shown below that:

  • Defines two static arrays of data that we will use for the repeater.
  • An onReady() function that:
    • Sets the initial data of the repeater.
    • Adds the event handlers that make the buttons work.
    • Adds the repeater onItemReady() and onItemRemoved() event handlers that run when new items are created and removed.
Copy
1
const sampleData1 = [
2
{"_id": "1", "content": "First item"},
3
{"_id": "2", "content": "Second item"}
4
];
5
6
const sampleData2 = [
7
{"_id": "3", "content": "Third item"},
8
{"_id": "4", "content": "Fourth item"}
9
];
10
11
$w.onReady(function () {
12
$w("#myRepeater").data = sampleData1;
13
14
$w("#addButton").onClick( (event, $w) => {
15
let repeaterData = $w("#myRepeater").data;
16
$w("#myRepeater").data = repeaterData.concat(sampleData2);
17
} );
18
19
$w("#removeButton").onClick( (event, $w) => {
20
$w("#myRepeater").data = sampleData1;
21
} );
22
23
$w("#updateButton").onClick( (event, $w) => {
24
let repeaterData = $w("#myRepeater").data;
25
repeaterData[0].content = "Changed item";
26
$w("#myRepeater").data = repeaterData;
27
28
$w("#myRepeater").forItems( ["1"], ($w, itemData, index) => {
29
$w("#repeatedId").text = itemData._id;
30
$w("#repeatedText").text = itemData.content;
31
} );
32
} );
33
34
$w("#myRepeater").onItemReady( ($w, itemData, index) => {
35
$w("#repeatedId").text = itemData._id;
36
$w("#repeatedText").text = itemData.content;
37
} );
38
39
$w("#myRepeater").onItemRemoved( (itemData) => {
40
console.log(`Removed: ${itemData.content}`);
41
} );
42
} );

Scenario

We will now run through a simple scenario to demonstrate the complete item lifecycle.


When the page first loads, the onReady() function runs, setting all the event handlers mentioned above and setting the value of the repeater's data property to be the first array of sample data.

Copy
1
$w("#myRepeater").data = sampleData1;

That means, when the page loads, the repeater's single item defined in the Editor will be replaced by two new items. The onItemRemoved() event handler does not run for the item that was removed because it was a static item defined in the Editor. However, the onItemReady() event handler runs for each of the new items that are added. In our case, we've defined the event handler to set the text values of the repeated item's elements from the corresponding data in the repeater's data array.

The repeater now looks like this:


If we then click the Add button, the repeater's data property is reset with a new array that contains the elements from both sample data arrays.

Copy
1
let repeaterData = $w("#myRepeater").data;
2
$w("#myRepeater").data = repeaterData.concat(sampleData2);

Because two of the elements in the data array are new, two corresponding new items are added to the repeater and the onItemReady() event handler runs once for each of these new items.

The repeater now looks like this:


If we then click the Remove button, the repeater's data property is reset back to the first array of sample data.

Copy
1
$w("#myRepeater").data = sampleData1;

Because two of the elements from the data array are removed, the two corresponding items are removed from the repeater and the onItemRemoved() event handler runs once for each of these removed items.

Copy
1
$w("#myRepeater").onItemRemoved( (itemData) => {
2
console.log(`Removed: ${itemData.content}`);
3
} );

The repeater now looks like this:


Finally, if we click the Update button, the repeater's data property is reset with an array with the same items as before, but with one value changed.

Copy
1
let repeaterData = $w("#myRepeater").data;
2
repeaterData[0].content = "Changed item";
3
$w("#myRepeater").data = repeaterData;

Because the IDs of the elements in the data array have not changed, nothing happens automatically. We need to manually call the forItems() function to update the elements in the corresponding repeated item.

Copy
1
$w("#myRepeater").forItems( ["1"], ($w, itemData, index) => {
2
$w("#repeatedId").text = itemData._id;
3
$w("#repeatedText").text = itemData.content;
4
} );

The repeater now looks like this:

Was this helpful?
Yes
No