APL Conditional Component Inflation
Conditional component inflation determines which components and layouts to inflate in an APL document. For example, the mainTemplate
property of an APL document accepts an array of components in the items
property, but renders a single component. Conditional component inflation determines which one to inflate. The component inflation algorithms enable lightweight conditional expressions using arrays of components, the when
property in primitive components, and data-binding.
Conditional inflation scenarios
Conditional inflation works differently depending on the scenario:
- Single child – Alexa inflates a single component from an array of possible components.
- Simple array – Alexa inflates a subset of components from an array of components.
- Data array – Alexa uses a data array to inflate a set of components.
Single child
With single child inflation, Alexa inflates at most one child component from an array of components. For example, the mainTemplate
property in an APL document might have multiple components in the items
array, but Alexa inflates a single component from the array.
- Used by – Components that accept an array of components in
items
, but inflate a single child. This includes:mainTemplate.items
array in a document.- User-defined layouts.
- Components that support a single child component:
ScrollView
,Frame
, andTouchWrapper
. - Properties on multi-child components that inflate a single child such as
firstItem
andlastItem
.
- Algorithm – Given an array of components, evaluate the
when
property of each component in turn. Use first component with awhen
property that evaluates totrue
. If no component has atrue
when
property, no component is inflated. Note that if thewhen
property is omitted, it defaults totrue
. - Data-binding – None
Sample single child inflation
In this example, a round viewport inflates the Container
, and a rectangular viewport inflates the Frame
.
"myLayout":
{
"parameters": [
"title",
"logo"
],
"item": [
{
"when": "${viewport.shape == 'round'}",
"type": "Container",...
},
{
"type": "Frame",...
}
]
}
Single child inflation and mainTemplate
A common error is to place multiple components in the mainTemplate
array. Because the mainTemplate
property in an APL document uses single child inflation, the first component where when
is true
displays, and the other components never display.
The when
property defaults to true
when not provided. The following example shows this scenario. The second Text
component never displays.
To use mainTemplate
correctly, use a when
clause to make the top-level components conditional. For example, change the first component to include a when
property that sometimes evaluates to false
. In the following example, the first component displays on round viewports and the second component displays on all other types of viewports:
{
"when": "${viewport.shape == 'round'}",
"type": "Text",
"padding": 20,
"text": "This is the first child component in <tt>mainTemplate</tt>. It doesn't specify <tt>when</tt>, so <tt>when</tt> defaults to <tt>true</tt>. Therefore, this component always displays."
}
To display multiple components at the same time, you must place them inside a multi-child component such as a Container
or Sequence
.
Simple array of child components
With simple array inflation, Alexa inflates a subset of components from an array of components. For example, you can pass an array of separate components to a the items
property of a Container
. Alexa renders each item in the array.
- Used by – Multiple-child components when the
data
property isn't set:Container
GridSequence
Pager
Sequence
- Algorithm – Evaluate the
when
property of each component in the array. If thewhen
clause evaluates totrue
, inflate the component and add it to the array of children. - Data-binding – The
index
,length
, andordinal
(optional) values are bound. See Data-binding.
Use a simple array of items when you have a collection of heterogeneous items to render in a multiple-child component.
The following example passes three components to a Container
in the items
array. The Text
heading is always displayed, an image is displayed when the viewport width
is less than the viewport height
, and the Text
leader is always displayed.
{
"type": "Container",
"padding": 20,
"items": [
{
"type": "Text",
"style": "heading",
"text": "Mars rover Opportunity is declared dead"
},
{
"type": "Image",
"when": "${viewport.width < viewport.height}",
"spacing": "@spacingMedium",
"height": "25%",
"width": "90%",
"scale": "best-fill",
"alignSelf": "center",
"source": "https://www.example.com/mars-rover.jpg"
},
{
"type": "Text",
"style": "textStyleBody",
"spacing": "@spacingMedium",
"text": "After fifteen years without any signal, the Mars rover Opportunity has ...}"
}
]
}
The following APL document shows this example. The example uses a placeholder for the image, and moves the text and image source into a separate data source. Select the Mobile Small Portrait viewport to see a case in which the when
clause is true
. This example also imports the alexa-styles
package to standardize the visual presentation.
Data array
With data array inflation, Alexa uses an array of data to inflate a set of components. This method is available for multiple-child components when the data
property is set.
- Used by &ndash Multiple-child components when the
data
property is set to an array of data:Container
GridSequence
Sequence
Pager
- Algorithm – Each element in the provided
data
array is bound in turn to "data" in the data-binding context. For each bound element, use the single child algorithm to find a single component. - Data-binding – The
data
,index
,length
, andordinal
(optional) values are bound.
See Data binding.
Use the data array approach when you have an array of data that you want to concatenate together and display. You define the set of components to inflate. Alexa renders that set of components for each item in data.
For example, consider displaying the steps in a recipe. You could define a Container
with a Text
component that displays a single step. Then, pass an array of strings in the data
property to provide the steps. Alexa inflates the Text
component one time for each string in the data
array. The Text
component has access to the data
, ordinal
, and index
properties for each item in the array.
{
"type": "Container",
"padding": 20,
"direction": "column",
"numbered": true,
"item": {
"type": "Text",
"text": "${ordinal}. ${data}",
"spacing": 20
},
"data": [
"Preheat the oven to 350 degrees F.",
"Using a mixer, cream the butter and sugar until smooth",
"With the mixer on, add one egg at a time to the butter-sugar mixture and beat until smooth",
"Combine the flour, baking powder, and salt in a separate ...."
]
}
The following APL document shows this Container
example in a document. The list of recipe steps are in an array in the data source.
You can also use data array inflation combined with the when
property to inflate a heterogeneous set of data. In the following example, the items
array for the Sequence
contains two components: a Text
component and a Container
. The Text
component uses the when
property to display for each data item that has the header
property. The Container
displays for the data items without this property.
{
"type": "Sequence",
"height": "100%",
"numbered": true,
"padding": 20,
"items": [
{
"when": "${data.header}",
"type": "Text",
"text": "${data.header}",
"numbering": "reset",
"fontWeight": "bold"
},
{
"type": "Container",
"direction": "row",
"alignItems": "center",
"items": [
{
"type": "Image",
"source": "${data.url}"
},
{
"type": "Text",
"text": "${ordinal}. ${data.caption}",
"spacing": 20
}
]
}
],
"data": [
{
"header": "Beach Photos"
},
{
"url": "https://images.example.com/photos/248797/xxx.jpg",
"caption": "Scene 248797"
},
{
"url": "https://images.example.com/photos/237739/yyy.jpg",
"caption": "Beach Boat Clouds Daylight 237739"
},
{
"header": "Dog Photos"
},
{
"url": "https://images.example.com/photos/356378/zzz.jpg",
"caption": "Adorable Animal Breed Canine 356378"
}
]
}
The following document shows this example. Note that the example uses image placeholders instead of actual images. The example also moves the data
array to the data source.
Related topics
Last updated: Nov 28, 2023