# Data-binding Syntax (APL for Audio)

**Note:**This functionality is offered as a public beta and may be changed, improved, or corrected as we receive feedback and iterate on the feature.

You use *data-binding syntax* to write expressions that Alexa evaluates when rendering your document. You use data-binding expressions to bind component properties to your data source, and to write conditional logic to include and exclude components depending on criteria.

## About data binding expressions

You use data binding expressions inside JSON strings. A data binding expression has the form "`${expression}`

".

You can use any number of expressions inside a string, for example: `"${2}+${2} = ${2+2}"`

.

Alexa evaluates expressions within the current data-binding context. The data-binding context is a global dictionary that supports booleans, numbers, strings, arrays, objects, and null.

## Supported value types

### Identifier

An identifier is a name used to identify a data-binding variable. Identifiers must follow the C identifier naming convention: `[a-zA-Z_][a-zA-Z0-9_]*`

. That is, the identifier must start with an upper or lower-case ASCII letter or underscore and can be followed by zero or more ASCII letters, numbers, or the underscore:

```
${data}
${_myWord23}
${__AnUgly26_letter__examplE}
```

### String literals

Define strings with either single or double quotes. The starting and ending quote must match. Quotes, carriage returns, and line-feeds can be escaped:

```
${"Double-quoted string"}
${'Single-quoted string'}
${"Inner quote: \" or '"}
```

Expressions can be nested inside of a string:

```
${"Two plus two is ${2+2}"}
```

### Numbers

Positive, negative, and floating-point numbers are supported. Scientific notation is not supported. All numbers are doubles.

### Booleans

Boolean values of true and false are supported:

```
${true}
${false}
```

### Time

Time data types are supported, with a default unit of milliseconds. The only supported units are milliseconds and seconds. Use a suffix of "s" to indicate a unit of "seconds":

```
${1000}
${1.7s}
```

### null

The null constant is supported:

```
${null}
```

## Truthy and coercion

Data-binding expressions use different types. These types can be converted into other types. The following table summarizes these type conversions:

Object Type | Example | As Boolean | As Number | As String |
---|---|---|---|---|

Null | null | false | 0 | "" |

Boolean | true | true | 1 | "true" |

false | false | 0 | "false" | |

Number | 23 | true | 23 | "23" |

0 | false | 0 | "0" | |

String | "My dog" | true | 0 | "My dog" |

"" | false | 0 | "" | |

"-2.3" | true | -2.3 | "-2.3" | |

"red" | true | 0 | "red" | |

"50vw" | true | 50 | "50vw" | |

Array | [] | true | 0 | "" |

Map | {} | true | 0 | "" |

0vh | false | 0 | "0ch" | |

23% | true | 0.23 | "23%" | |

0% | false | 0 | "0%" | |

auto | true | 0 | "auto" | |

Anything else | … | true | 0 | "" |

### Boolean coercion

A truthy value is a value that is considered true when evaluated in a boolean context. All values are truthy except for `false`

, 0, "", and `null`

.

### Number coercion

The boolean "true" value converts to the number 1. Everything else converts to 0.

### String coercion

Internal types convert to strings according to the rules in the following table:

Object | Example | Result | Description |
---|---|---|---|

Null | null | `''` |
The null value is not rendered. |

Boolean | true false | `'true'` `'false'` |
Boolean true & false are rendered as strings. |

Number | -23 | `'-23'` |
Integers have no decimal places. |

1/3 | `'0.333333'` |
Non-integers have decimal places. | |

String | "My "dog" " | `'My "dog" '` |
String values |

Array | […] | `''` |
Arrays are not rendered |

Map | {…} | `''` |
Maps are not rendered |

Anything else | `${Math.min}` |
`''` |
Math functions are not rendered. |

The specific format of non-integer numbers is not defined, but should follow the C++ standard for `sprintf(buf, "%f", value)`

. This format might change based on the locale.

## Operators

### Arithmetic operators

The standard arithmetic operations for addition, subtraction, multiplication, division, and remainder are supported:

```
${1+2} // 3
${1-2} // -1
${1*2} // 2
${1/2} // 0.5
${1%2} // 1.
```

Addition and subtraction work for pairs of numbers.

The addition operator also acts as a string-concatenation operator if either the left or right operand is a string:

```
${27+""} // '27'
${1+" dog"} // '1 dog'
${"have "+3} // 'have 3'
```

Multiplication, division, and the remainder operator work for pairs of numbers.

The remainder operator behaves as in JavaScript:

```
${10 % 3} // 1
${-1 % 2} // -1
${3 % -6} // 3
${6.5 % 2} // 0.5
```

### Logical operators

The standard logical and/or/not operators are supported:

```
${true || false} // true
${true && false} // false
${!true} // false
```

The && returns the first operand when the operand is not truthy and the second otherwise. The | operator returns the first operand if it is truthy and the second otherwise: |

```
${7 && 2} // 2
${null && 3} // null
${7 || 2} // 7
${0 || -16} // -16
```

### Comparison operators

Comparison operators return boolean values:

```
${1 < 2}
${75 <= 100}
${3 > -1}
${4 >= 4}
${myNullValue == null}
${(2>1) == true}
${1 != 2}
```

The comparison operators don't apply to arrays and objects.

### Null coalescing operator

The `??`

operator is the *null-coalescing operator*. It returns the left-hand operand if the operand is not null; otherwise it returns the right-hand operand. You can chain the null-coalescing operator:

```
${person.name ?? person.surname ?? 'Hey, you!'}
```

The null-coalescing operator returns the left-hand operand when it is anything but null:

```
${1==2 ?? 'Dog'} // returns false
${1==2 || 'Dog'} // returns 'Dog'
```

### Ternary operator

The *ternary conditional operator* (`${a ? b : c}`

) evaluates the left-hand operand. If it evaluates to true or a truthy value, the middle operand is returned. Otherwise the right-hand operand is returned:

```
${person.rank > 8 ? 'General' : 'Private'}
```

## Array and object access

### Array

Array access uses the `[]`

operator, where the operand should be an integer. Arrays also support the `.length`

operator to return the length of the array. Accessing an element outside of the array bounds returns null:

```
${myArray[4]} // 5th element in the array (0-indexed)
${myArray.length} // Length of the array
${myArray[-1])} // Last element in the array
${myArray[myArray.length]} // Returns null (out of bounds)
```

Passing a negative index counts backwards through the array:

```
${a[-1] == a[a.length - 1]} // True
```

### Object

Objects support the `.`

operator and the `[]`

array access operator with string values:

```
${myObject.name} // The 'name' property of myObject
${myObject['name']} // The 'name' property of myObject
```

An undefined property returns null. Calling the `.`

or `[]`

operator on null returns null:

```
${myNullObject.address.zipcode} // Returns null
```

The right-side operand of the dot operator must be a valid identifier.

## Function calls

### Functions

Data-binding supports a limited number of built-in functions. Functions use the form:

```
functionName( arg1, arg2, … )
```

Functions don't require arguments. A function returns a single value.

### Built-in functions

Property | Description | Example |
---|---|---|

`Math.abs(x)` |
Return the absolute value of x | `${Math.abs(-2.3)} == 2.3` |

`Math.acos(x)` |
The arccosine of x | `${Math.acos(1)} == 0` |

`Math.asin(x)` |
The arcsine of x | `${Math.asin(0)} == 0` |

`Math.atan(x)` |
The arctangent of x | `${Math.atan(1)} == 0.7853981633974483` |

`Math.ceil(x)` |
Return the smallest integer greater than or equal to x. | `${Math.ceil(2.3)} == 3` |

`Math.clamp(x,y,z)` |
Return x if y<x, z if y>z and otherwise y. | `${Math.clamp(1, 22.3,10)} == 10` |

`Math.cos(x)` |
The cosine of x | `${Math.cos(0)} == 1` |

`Math.floor(x)` |
Return the largest integer less than or equal to x. | `${Math.floor(2.3)} = 2` |

`Math.max(x1,x2,…)` |
Return the largest argument | `${Math.max(2,3)} == 3` |

`Math.min(x1,x2,…)` |
Return the smallest argument | `${Math.min(2,3)} == 2` |

`Math.PI` |
The value of π | 3.141592653589793 |

`Math.random()` |
A random number between 0 and 1 | `${Math.random()} == 0.7113654073137101` (but not every time!) |

`Math.round(x)` |
Return the nearest integer to x | `${Math.round(2.3)} == 2` |

`Math.sign(x)` |
The sign of x: -1, 0, or +1 | `${Math.sign(-43.1) == -1` |

`Math.sin(x)` |
The sine of x | `${Math.sin(Math.PI/6)} == 0.5` |

`Math.sqrt(x)` |
The square root of x | `${Math.sqrt(9)} == 3` |

`Math.tan(x)` |
The tangent of x | `${Math.tan(Math.PI/4)} == 0.5` |

`String.slice(x,y[,z])` |
Return the subset of x starting at index y and extending to but not including index z. If z is omitted, the remainder of the string is returned. If y is a negative number, select from the end of the string. | `${String.slice("berry", 2, 4)} == "rr"` `${String.slice("berry", -2)} == "ry"` |

`String.toLowerCase(x)` |
Return a lower-case version of x | `${String.toLowerCase("bEn")} == "ben"` |

`String.toUpperCase(x)` |
Return an upper-case version of x | `${String.toUpperCase("bEn")} == "BEN"` |

## Data-binding string conversion

Because APL is serialized in JSON, all data-bound expressions are defined inside of a JSON string:

```
{
"MY_EXPRESSION": "${....}"
}
```

If there are no spaces between the quotation marks and the data-binding expression, the result of the expression is the result of the data-binding evaluation. For example:

```
"${true}" -> Boolean true
"${2+4}" -> Number 6
"${0 <= 1 && 'three'}" -> String 'three'
```

When extra spaces are in the string outside of the data-binding expression or when two data-binding expressions are juxtaposed, the result is a string concatenation:

```
" ${true}" -> String ' true'
"${2+4} " -> String '6 '
"${2+1}${1+2}" -> String '33'
```