List

A List variable stores an ordered collection of values, internally treated as a JSON array. It's ideal for managing multiple items of the same type, such as product lists, user arrays, menu items, or any sequential data.

When to Use

Use List variables when you need to:

  • Store collections of items (products, users, posts)

  • Manage arrays returned from API calls

  • Populate ListView, GridView, or Carousel widgets

  • Track multiple selections or tags

  • Store ordered data that needs indexing

  • Iterate over a collection of items

Structure

Lists are ordered collections enclosed in square brackets:

["Apple", "Banana", "Orange"]
[1, 2, 3, 4, 5]
[
  {"name": "John", "age": 30},
  {"name": "Jane", "age": 25},
  {"name": "Bob", "age": 35}
]

Common Use Cases

1. Data Source for Lists

Power ListView, GridView, or Carousel widgets:

Variable: products (List)
Value: [
  {"id": 1, "name": "Laptop", "price": 999},
  {"id": 2, "name": "Phone", "price": 599},
  {"id": 3, "name": "Tablet", "price": 399}
]

ListView:
  Data Source: ${products}
  
  Child Template:
    Text: ${currentItem.name}
    Text: ${concat("$", currentItem.price)}

2. API Response Arrays

Store lists returned from APIs:

Variable: userList (List)
Initial Value: []

On API Success:
  Set State: userList = ${apiResponse.data.users}

ListView:
  Data Source: ${userList}

3. Multiple Selections

Track selected items:

Variable: selectedItems (List)
Initial Value: []

Note: To add/remove items from a list, you can:
- Use an API endpoint that returns the updated list
- Create a custom JavaScript function to handle array operations

Text Widget:
  Text: ${concat("Selected: ", selectedItems.length, " items")}

4. Tags or Categories

Store multiple tags:

Variable: tags (List)
Value: ["featured", "new", "sale", "trending"]

Row (with dynamic children):
  Data Source: ${tags}
  
  Chip Widget:
    Label: ${currentItem}

5. Simple Arrays

Store simple value lists:

Variable: colors (List)
Value: ["red", "blue", "green", "yellow"]

Variable: numbers (List)
Value: [10, 20, 30, 40, 50]

Accessing List Data

By Index

Access items using zero-based index:

${myList[0]}          // First item
${myList[1]}          // Second item
${myList[2]}          // Third item

Or use the elementAt function:

${elementAt(myList, 0)}   // First item
${elementAt(myList, 1)}   // Second item

First and Last Elements

Get the first or last item directly:

${firstElement(myList)}   // First item
${lastElement(myList)}    // Last item

Length

Get the number of items:

${myList.length}

In Loops (currentItem)

When used as a data source in ListView/GridView:

${currentItem}        // Current item in the iteration
${index}              // Current index (0-based)

Modifying Lists

Adding Items

Add items using standard array notation or API responses:

Set State: myList = ${apiResponse.data.items}

Note: For adding individual items, use JSON operators to create a new array with the added item.

Clearing List

Empty the entire list:

Set State: myList = []

Working with Lists

List Operators

Use list-specific operators for manipulation. Available functions include:

  • contains() - Check if item exists in the list

  • elementAt() - Access element at specific index

  • firstElement() - Get the first element

  • lastElement() - Get the last element

  • skip() - Skip first N elements

  • take() - Take first N elements

  • reversed() - Reverse the order of elements

See the JSON Operators documentation for all available array functions.

Checking for Items

Verify if an item exists:

${contains(myList, searchItem)}
${gt(myList.length, 0)}

Taking Subsets

Extract portions of the list:

${take(myList, 5)}        // First 5 items
${skip(myList, 10)}       // Skip first 10 items
${take(skip(myList, 5), 10)}  // Skip 5, then take 10

Reversing

Reverse the order:

${reversed(myList)}

Common Patterns

Empty State Handling

Check if list is empty:

Conditional Builder:
  Condition: ${gt(myList.length, 0)}
  True: ListView with data
  False: "No items found" message

Accessing First/Last Item

Text: ${firstElement(myList)}
Text: ${lastElement(myList)}

Checking if Empty

${isEqual(myList.length, 0)}
${gt(myList.length, 0)}

Displaying Count

Text: ${concat("Total items: ", myList.length)}
Text: ${concat(myList.length, " results found")}

Showing Limited Items

ListView:
  Data Source: ${take(myList, 5)}  // Show only first 5 items

Pagination Pattern

Variable: currentPage (Number)
Value: 1

Variable: itemsPerPage (Number)
Value: 10

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

Iterating in UI

ListView:
  Data Source: ${myList}
  
  Child:
    Text: ${currentItem.name}
    Text: ${concat("Item #", sum(index, 1))}

List of Objects vs List of Primitives

List of Objects

Best for complex data with multiple properties:

[
  {"id": 1, "name": "Alice", "role": "Admin"},
  {"id": 2, "name": "Bob", "role": "User"}
]

Access: ${currentItem.name}

List of Primitives

Best for simple values:

["red", "blue", "green"]
[10, 20, 30, 40]

Access: ${currentItem}

Best Practices

  • Initialize with empty array: Start with [] if no initial data, to avoid null errors

  • Use for homogeneous data: Lists work best when all items have the same structure

  • Check length before accessing: Always verify myList.length > 0 before accessing items

  • Handle empty states: Provide UI feedback when lists are empty

  • Use appropriate data structures: Use List for arrays, JSON for single objects

  • Keep items consistent: If storing objects, ensure all have the same properties

  • Index safety: Check bounds before accessing by index to avoid errors

  • Immutable updates: When modifying, create new arrays rather than mutating directly

Performance Considerations

  • Lazy rendering: Use ListView/GridView for long lists—they render items on-demand

  • Avoid large static lists: For very large datasets, fetch data in pages/chunks

  • Filter efficiently: Filter lists before passing to UI widgets when possible

  • Minimize re-renders: Only update the list when necessary to avoid performance issues

Last updated