adev/src/content/guide/templates/expression-syntax.md
Angular expressions are based on JavaScript, but differ in some key ways. This guide walks through the similarities and differences between Angular expressions and standard JavaScript.
Angular supports a subset of literal values from JavaScript.
| Literal type | Example values |
|---|---|
| String | 'Hello', "World" |
| Boolean | true, false |
| Number | 123, 3.14 |
| Object | {name: 'Alice'} |
| Array | ['Onion', 'Cheese', 'Garlic'] |
| null | null |
| RegExp | /\d+/ |
| Template string | `Hello ${name}` |
| Tagged template string | tag`Hello ${name}` |
| Literal type | Example values |
|---|---|
| BigInt | 1n |
Angular expressions support the following globals:
No other JavaScript globals are supported. Common JavaScript globals include Number, Boolean, NaN, Infinity, parseInt, and more.
Angular automatically makes special local variables available for use in expressions in specific contexts. These special variables always start with the dollar sign character ($).
For example, @for blocks make several local variables corresponding to information about the loop, such as $index.
Angular supports the following operators from standard JavaScript.
| Operator | Example(s) |
|---|---|
| Add / Concatenate | 1 + 2 |
| Subtract | 52 - 3 |
| Multiply | 41 * 6 |
| Divide | 20 / 4 |
| Remainder (Modulo) | 17 % 5 |
| Exponentiation | 10 ** 3 |
| Parenthesis | 9 * (8 + 4) |
| Conditional (Ternary) | a > b ? true : false |
| And (Logical) | && |
| Or (Logical) | || |
| Not (Logical) | ! |
| Nullish Coalescing | possiblyNullValue ?? 'default' |
| Comparison Operators | <, <=, >, >=, ==, ===, !==, != |
| Unary Negation | -x |
| Unary Plus | +y |
| Property Accessor | person['name'] |
| typeof | typeof 42 |
| void | void 1 |
| in | 'model' in car |
| instanceof | car instanceof Automobile |
| Assignment | a = b |
| Addition Assignment | a += b |
| Subtraction Assignment | a -= b |
| Multiplication Assignment | a *= b |
| Division Assignment | a /= b |
| Remainder Assignment | a %= b |
| Exponentiation Assignment | a **= b |
| Logical AND Assignment | a &&= b |
| Logical OR Assignment | a ||= b |
| Nullish Coalescing Assignment | a ??= b |
| Spread in object literals | {...obj, foo: 'bar'} |
| Spread in array literals | [...arr, 1, 2, 3] |
| Rest in function calls | fn(...args) |
Angular expressions additionally also support the following non-standard operators:
| Operator | Example(s) |
|---|---|
| Pipe | {{ total | currency }} |
| Optional chaining* | someObj.someProp?.nestedProp |
| Non-null assertion (TypeScript) | someObj!.someProp |
Prior to Angular 22, the optional chaining operator (?.) returned null when the left-hand side is null or undefined, whereas standard JavaScript's ?. returns undefined.
Since Angular 22, the optional chaining operator behavior in angular expressions is alligned with the standard Javascript's behavior.
During the migration to v22, the ng update schematics added a $safeNavigationMigration magic function to existing expressions to preserve the previous null-returning behavior.
{{ $safeNavigationMigration(foo?.bar) }}
$safeNavigationMigration is a temporary migration aid only. It instructs the compiler to compile the wrapped safe-navigation expression using the legacy null-returning semantics rather than the standard JavaScript ?. semantics. It is not a real function and cannot be called from TypeScript.
NOTE: Prefer migrating expressions to no longer rely on null vs undefined distinctions so that $safeNavigationMigration can be removed. This function may be removed in a future version of Angular.
| Operator | Example(s) |
|---|---|
| All bitwise operators | &, &=, ~, |=, ^=, etc. |
| Object destructuring | const { name } = person |
| Array destructuring | const [firstItem] = items |
| Comma operator | x = (x++, x) |
| new | new Car() |
Angular expressions are evaluated within the context of the component class as well as any relevant template variables, locals, and globals.
When referring to component class members, this is always implied. However, if a template declares a template variables with the same name as a member, the variable shadows that member. You can unambiguously reference such a class member by explicitly using this.. This can be useful when creating an @let declaration that shadows a class member, e.g. for signal narrowing purposes.
Generally speaking, declarations are not supported in Angular expressions. This includes, but is not limited to:
| Declarations | Example(s) |
|---|---|
| Variables | let label = 'abc', const item = 'apple' |
| Functions | function myCustomFunction() { } |
| Arrow Functions | () => { } |
| Classes | class Rectangle { } |
Event handlers are statements rather than expressions. While they support all of the same syntax as Angular expressions, there are two key differences: