Iterable Operators

Iterable operators allow you to work with collections of data such as lists and arrays. These operators help you access, filter, and manipulate elements within your data structures.


Available Operators

contains()

Checks if a collection contains a specific element.

Syntax:

${contains(collection, element)}

Parameters:

  • collection - The list or array to search in

  • element - The value to search for

Returns: true if the element exists in the collection, false otherwise

Examples:

// Check if a list contains a value
${contains(["apple", "banana", "orange"], "banana")}
// Returns: true

${contains([1, 2, 3, 4, 5], 6)}
// Returns: false

// Check if user's tags include "premium"
${contains(user.tags, "premium")}

// Conditional based on contains
${if(contains(selectedItems, currentItem.id), "Selected", "Not Selected")}

Use Cases:

  • Verify if an item is in a selection

  • Check if a user has a specific permission or tag

  • Validate if a value exists before processing

  • Implement toggle functionality (add/remove from list)


elementAt()

Returns the element at a specific index in a collection.

Syntax:

${elementAt(collection, index)}

Parameters:

  • collection - The list or array

  • index - Zero-based index position (0 for first element, 1 for second, etc.)

Returns: The element at the specified index, or null if index is out of bounds

Examples:

// Get the first element
${elementAt(["apple", "banana", "orange"], 0)}
// Returns: "apple"

// Get the third element
${elementAt([10, 20, 30, 40], 2)}
// Returns: 30

// Get element by variable index
${elementAt(products, selectedIndex)}

// Use in expressions
${concat("Selected: ", elementAt(items, currentIndex))}

Use Cases:

  • Access specific items by position

  • Get items based on calculated indices

  • Retrieve elements when index comes from user input or state

  • Alternative to bracket notation myList[index]


firstElement()

Returns the first element of a collection.

Syntax:

${firstElement(collection)}

Parameters:

  • collection - The list or array

Returns: The first element, or null if the collection is empty

Examples:

// Get first item
${firstElement(["apple", "banana", "orange"])}
// Returns: "apple"

${firstElement([1, 2, 3, 4, 5])}
// Returns: 1

// Display first product name
${firstElement(products).name}

// With fallback for empty list
${if(gt(length(items), 0), firstElement(items), "No items available")}

Use Cases:

  • Show the most recent item (if list is sorted by date)

  • Get the top result from search or filter

  • Display featured or highlighted item

  • Quick access to first element without indexing


lastElement()

Returns the last element of a collection.

Syntax:

${lastElement(collection)}

Parameters:

  • collection - The list or array

Returns: The last element, or null if the collection is empty

Examples:

// Get last item
${lastElement(["apple", "banana", "orange"])}
// Returns: "orange"

${lastElement([1, 2, 3, 4, 5])}
// Returns: 5

// Display last message
${lastElement(messages).text}

// Show latest timestamp
${lastElement(history).timestamp}

Use Cases:

  • Show the most recent item (if appending to end)

  • Display the final element without calculating index

  • Access last page in pagination

  • Get the latest entry in chronological data


skip()

Returns a new collection that skips the first N elements.

Syntax:

${skip(collection, count)}

Parameters:

  • collection - The list or array

  • count - Number of elements to skip from the beginning

Returns: A new collection with the first count elements removed

Examples:

// Skip first 2 elements
${skip(["a", "b", "c", "d", "e"], 2)}
// Returns: ["c", "d", "e"]

${skip([1, 2, 3, 4, 5], 3)}
// Returns: [4, 5]

// Pagination: Skip to page 2 (skip first 10 items)
${skip(allItems, 10)}

// Combined with take for pagination
${take(skip(products, mul(diff(currentPage, 1), itemsPerPage)), itemsPerPage)}

Use Cases:

  • Implement pagination (skip previous pages)

  • Remove header rows from data

  • Start displaying from a certain position

  • Offset-based data loading


take()

Returns a new collection containing only the first N elements.

Syntax:

${take(collection, count)}

Parameters:

  • collection - The list or array

  • count - Number of elements to take from the beginning

Returns: A new collection with only the first count elements

Examples:

// Take first 3 elements
${take(["a", "b", "c", "d", "e"], 3)}
// Returns: ["a", "b", "c"]

${take([1, 2, 3, 4, 5], 2)}
// Returns: [1, 2]

// Show only top 5 items
${take(products, 5)}

// Limit display to 10 results
ListView:
  Data Source: ${take(searchResults, 10)}

Use Cases:

  • Limit number of displayed items

  • Show "top N" results

  • Preview or teaser lists (e.g., "Top 5 Products")

  • Implement "Show More" functionality


reversed()

Returns a new collection with elements in reverse order.

Syntax:

${reversed(collection)}

Parameters:

  • collection - The list or array to reverse

Returns: A new collection with elements in opposite order

Examples:

// Reverse a list
${reversed(["a", "b", "c", "d"])}
// Returns: ["d", "c", "b", "a"]

${reversed([1, 2, 3, 4, 5])}
// Returns: [5, 4, 3, 2, 1]

// Show messages in reverse chronological order
ListView:
  Data Source: ${reversed(messages)}

// Display countdown
${reversed(numbers)}

Use Cases:

  • Show newest items first (reverse chronological order)

  • Display data in descending order

  • Create countdown or reverse sequences

  • Reverse user selections


Combining Operators

You can chain multiple iterable operators together for powerful data manipulation:

Pagination Example

// Show items 11-20 (page 2, 10 items per page)
${take(skip(allItems, 10), 10)}

// Dynamic pagination
Variable: currentPage = 2
Variable: itemsPerPage = 10

ListView:
  Data Source: ${take(skip(products, mul(diff(currentPage, 1), itemsPerPage)), itemsPerPage)}

Limited Reversed List

// Show last 5 items in reverse order
${take(reversed(items), 5)}

// Show 3 most recent messages
${take(reversed(messages), 3)}

Skip and Check

// Get all items except first one
${skip(items, 1)}

// Check if skipped list contains something
${contains(skip(tags, 2), "featured")}

Conditional Access

// Get first item if exists
${if(gt(items.length, 0), firstElement(items), "No items")}

// Get last element safely
${if(gt(length(products), 0), lastElement(products), defaultProduct)}

Common Patterns

Empty List Handling

Conditional Builder:
  Condition: ${gt(items.length, 0)}
  
  True Child:
    Text: ${firstElement(items).name}
  
  False Child:
    Text: "No items available"

Show Limited Preview

// Show first 3 items with "View All" option
Column:
  Children:
    ListView:
      Data Source: ${take(products, 3)}
    
    Button:
      Text: "View All"
      Visible: ${gt(products.length, 3)}

Pagination Controls

Variable: currentPage (Number) = 1
Variable: pageSize (Number) = 10

ListView:
  Data Source: ${take(skip(items, mul(diff(currentPage, 1), pageSize)), pageSize)}

Button (Next):
  Enabled: ${lt(mul(currentPage, pageSize), items.length)}
  onClick: Set State: currentPage = ${sum(currentPage, 1)}

Button (Previous):
  Enabled: ${gt(currentPage, 1)}
  onClick: Set State: currentPage = ${diff(currentPage, 1)}

Checking Selection State

// Toggle selection
Button:
  Text: ${if(contains(selectedItems, item.id), "Deselect", "Select")}
  Background: ${if(contains(selectedItems, item.id), "blue", "gray")}

Accessing Specific Elements

// Safe access with fallback
Text: ${if(isNotNull(elementAt(items, index)), elementAt(items, index), "Item not found")}

// Display range
Text: ${concat("Showing items ", sum(elementAt(items, 0).id, 1), " to ", lastElement(items).id)}

Best Practices

  • Check length before accessing: Always verify the collection has elements before using firstElement(), lastElement(), or elementAt()

  • Use appropriate operators: Choose firstElement() over elementAt(myList, 0) for clarity

  • Combine for pagination: Use skip() and take() together for efficient pagination

  • Cache results: If using the same operation multiple times, consider storing the result in a variable

  • Handle null cases: Use or() or conditional if() to provide fallbacks when elements might not exist

  • Mind performance: While operations are efficient, avoid deeply nested chains in large lists displayed in UI


Last updated