Nesting Dynamic Repeaters

Dynamic repeaters are repeaters that are intended to get their content dynamically. This means that their content can only come through a connection to a CMS collection, or through code. You cannot edit the content of each individual item directly on the canvas.

There are several ways to nest a dynamic repeater in another dynamic repeater. We recommend using nested widgets and drilling their properties.

This article uses a menu app as an example. Here is the app structure:

  • Several menu sections, such as appetizers, main courses, desserts.
  • Every section contains several dishes, such as salad, pasta, chocolate cake.

There are two collections in the app:

  • MenuSections: The outer collection, which stores sections.
  • RestaurantDishes: The inner one, which stores dishes.

Here's what the general structure of the app looks like:

menu structure

In this option uses nested widgets. The app has three widgets:

  • menuWidget: The top level widget, representing the entire menu.
  • sectionWidget: Represents each section and is nested in menuWidget.
  • dishWidget: Represents each individual dish and is nested in sectionWidget

Top level widget: menuWidget

The top level widget, menuWidget holds a repeater with the menu sections. It connects this repeater to the MenuSections collection using no code.

Since sectionWidget (the second level widget), has a repeater that connects to the RestaurantDishes collection, the top level widget can query both collections at once, using the include() method. All the information is then passed to the nested widgets through prop drilling.

Here is the code for menuWidget:

Copy

Second level widget: sectionWidget

The sectionWidget has two widget properties:

  • dishes [Dish]: A list of a properties of a  custom type representing a dish.
  • sectionTitle: A text property for the section's title.

dish type

Here is the code for sectionWidget:

Copy

Third level widget: dishWidget

The dishWidget has three simple properties:

  • title: Text property for the dish name.
  • description: Text property for the dish description.
  • image: Image property for the dish.

This is the code for dishWidget:

Copy

Option 2 | One nested widget

For this option, the app structure is simplified:

  • menuWidget: The top-level widget with a repeater connected to the main MenuSections collection.
  • sectionWidget: A nested widget with a repeater connected to the RestaurantDishes collection.
  • The nested widget has two widget properties: sectionId and sectionTitle.

Both repeaters connect their elements (texts and images) to their respective collections with no code.

Top level widget: menuWidget

The menuWidget uses code to pass the sectionId and sectionTitle to the nested widget, as widget properties cannot be connected to data with no code.

Notice that since the repeater is connected to a collection with no code, you can call onItemReady() without setting the repeater data explicitely.

Here is the code for menuWidget:

Copy

Nested widget: sectionWidget

The sectionWidget filters the repeater with the the sectionId and displays only the relevant dishes.

Here is the code for sectionWidget:

Copy

Notice that because the repeaters are nested, each of the collections receives a field that references to the dataset of the other collection.

collection structure

Option 3 | Code-only solution with one widget

This option uses a single widget with nested repeaters.

This is the widget structure:

  • The top level repeater is sections. It connects to the MenuSections collection.
  • The nested repeater is dishes. It connects to the RestaurantDishes collection.

The following query fetches the data from both collections, using the include() method.

Here is the widget code:

Copy

In this option, the outer repeater is connected to the MenuSections collection using no-code data binding. However, since only the top-level repeater can use data binding when nesting repeaters, the inner repeater must be connected programmatically.

To populate the inner repeater, we query its items using queryReferenced(). While this approach works, it is more performance-costly than the previous options because it requires an additional query for each nested item.

Copy
Did this help?