In keyword in binary expression of an HTML template

One of the new features in Angular 20.0.0-next.8 is the "in" keyword in binary expressions in templates. This keyword enables testing the existence of properties in an object before their values are interpolated in Angular expressions. Without it, the component class defines methods to perform the check and invokes them in the template. The Problem It Solves Supporting the "in" keyword in a template takes one step closer to making Angular expressions behave like TypeScript expressions. First, let's update Angular to the latest version 20. As of this writing, the Angular version is 20.0.0.next-9. ng update @angular/core @angular/cli --next In this demo, we will define Fish, Dog, and Cat interfaces that extend the Animal interface and possess distinct properties. In the AppComponent, there is an animals array typed as the union of Fish, Dog, and Cat. Since the array has polymorphic interfaces, the "in" keyword tests the existence of the properties before their values are displayed in Angular expressions, compared in the test condition of the if statement, and bound to CSS classes. Defining the Animal Type First, we define the interfaces of Animal, Dog, Cat, and Fish. export interface Animal {} export interface Fish extends Animal { swim: string; } export interface Dog extends Animal { noise: string; run: string; swim: string } export interface Cat extends Animal { noise: string; jump: string; } The Fish, Dog, Cat interfaces extend the Animal interface: Fish has a swim property only; Dog has noise, run, and swim properties, while Cat has noise and jump properties. Create Animals in AppComponent @Component({ selector: 'app-root', templateUrl: './app.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class AppComponent { animals: (Cat | Dog | Fish)[] = [ { noise: 'barks', run: 'a beach', swim: 'a swimming pool', }, { noise: 'meows', jump: 'on the sofa', }, { swim: 'an aquarium', }, ] } In the AppComponent, I initialized an animals array with instances of Cat, Dog, and Fish. Now, I demonstrated the "in" keyword in the HTML template of the AppComponent. Example 1: Use the In Keyword in the Expressions @for (animal of animals; track animal) { @let properties = ['swim', 'noise', 'run', 'jump']; @for (property of properties; track property) { {{ property in animal ? `${property} in animal` : `${property} not in animal` }} } } In this example, the for loop iterates the properties array to check the presence of the properties in the animal object. If the object has the property, the component displays "${property} in animal". Otherwise, the component displays "${property} not in animal". When the animal is a Dog, the results are: swim in animal noise in animal run in animal jump not in animal Case 2: Use the In Keyword in the new Control Flow Syntax @for (animal of animals; track animal) { @let canSwim = 'swim' in animal; @if (canSwim) { {{ `The animal swims in ${animal.swim}.` }} } @let canNoise = 'noise' in animal; @if (canNoise) { {{ `The animal ${animal.noise}.` }} } @let canRun = 'run' in animal; @if (canRun) { {{ `The animal runs in ${animal.run}.` }} } @let canJump = 'jump' in animal; @if (canJump) { {{ `The animal jumps in ${animal.jump}.` }} } } In this example, the "in" keyword in the binary expressions is evaluated, and the results are stored in the temporary variables. The if control flow tests the variables and renders the paragraph elements when the condition is true. When the animal is a Dog, the results are The animal swims in a swimming pool. The animal barks. The animal runs in a beach. Case 3: Bind the results of the In Keyword to CSS Classes .run { color: rebeccapurple; } .swim { color: goldenrod; } .jump { color: fuchsia; } .noise { color: crimson; } @for (animal of animals; track animal) { @let canSwim = 'swim' in animal; {{ `The animal swims in ${animal.swim}.` }} @let canNoise = 'noise' in animal; {{ `The animal ${animal.noise}.` }} @let canRun = 'run' in animal; {{ `The animal runs in ${animal.run}.` }} @let canJump = 'jump' in animal; {{ `The animal jumps in ${animal.jump}.` }} } In this example, the results of the "in" keyword are used to show or hide the CSS classes. If the animal object has the swim property, the swim class will be applied to the paragraph element, and the text will be rendered goldenrod. If the animal object has the noise property, the noise class will render the text crimson. If the animal object has the run property, the text color is rebeccapurple. Finally,

May 5, 2025 - 06:36
 0
In keyword in binary expression of an HTML template

One of the new features in Angular 20.0.0-next.8 is the "in" keyword in binary expressions in templates. This keyword enables testing the existence of properties in an object before their values are interpolated in Angular expressions. Without it, the component class defines methods to perform the check and invokes them in the template.

The Problem It Solves

Supporting the "in" keyword in a template takes one step closer to making Angular expressions behave like TypeScript expressions.

First, let's update Angular to the latest version 20. As of this writing, the Angular version is 20.0.0.next-9.

ng update @angular/core @angular/cli --next

In this demo, we will define Fish, Dog, and Cat interfaces that extend the Animal interface and possess distinct properties. In the AppComponent, there is an animals array typed as the union of Fish, Dog, and Cat. Since the array has polymorphic interfaces, the "in" keyword tests the existence of the properties before their values are displayed in Angular expressions, compared in the test condition of the if statement, and bound to CSS classes.

Defining the Animal Type

First, we define the interfaces of Animal, Dog, Cat, and Fish.

export interface Animal {}

export interface Fish extends Animal {
   swim: string;
}

export interface Dog extends Animal {
   noise: string;
   run: string;
   swim: string
}

export interface Cat extends Animal {
   noise: string;
   jump: string;
}

The Fish, Dog, Cat interfaces extend the Animal interface: Fish has a swim property only; Dog has noise, run, and swim properties, while Cat has noise and jump properties.

Create Animals in AppComponent

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
 animals: (Cat | Dog | Fish)[] = [
   {
     noise: 'barks',
     run: 'a beach',
     swim: 'a swimming pool',
   },
   {
     noise: 'meows',
     jump: 'on the sofa',
   },
   {
     swim: 'an aquarium',
   },
 ]
}

In the AppComponent, I initialized an animals array with instances of Cat, Dog, and Fish.

Now, I demonstrated the "in" keyword in the HTML template of the AppComponent.

Example 1: Use the In Keyword in the Expressions

@for (animal of animals; track animal) { @let properties = ['swim', 'noise', 'run', 'jump']; @for (property of properties; track property) {

{{ property in animal ? `${property} in animal` : `${property} not in animal` }} } }

In this example, the for loop iterates the properties array to check the presence of the properties in the animal object. If the object has the property, the component displays "${property} in animal". Otherwise, the component displays "${property} not in animal".

When the animal is a Dog, the results are:

  • swim in animal
  • noise in animal
  • run in animal
  • jump not in animal

Case 2: Use the In Keyword in the new Control Flow Syntax

@for (animal of animals; track animal) { @let canSwim = 'swim' in animal; @if (canSwim) {

{{ `The animal swims in ${animal.swim}.` }} } @let canNoise = 'noise' in animal; @if (canNoise) {

{{ `The animal ${animal.noise}.` }} } @let canRun = 'run' in animal; @if (canRun) {

{{ `The animal runs in ${animal.run}.` }} } @let canJump = 'jump' in animal; @if (canJump) {

{{ `The animal jumps in ${animal.jump}.` }} } }

In this example, the "in" keyword in the binary expressions is evaluated, and the results are stored in the temporary variables. The if control flow tests the variables and renders the paragraph elements when the condition is true.

When the animal is a Dog, the results are

  • The animal swims in a swimming pool.
  • The animal barks.
  • The animal runs in a beach.

Case 3: Bind the results of the In Keyword to CSS Classes

.run {
   color: rebeccapurple;
}

.swim {
   color: goldenrod;
}

.jump {
   color: fuchsia;
}

.noise {
   color: crimson;
}
@for (animal of animals; track animal) { @let canSwim = 'swim' in animal; [class.swim]="canSwim">{{ `The animal swims in ${animal.swim}.` }} @let canNoise = 'noise' in animal; [class.noise]="canNoise">{{ `The animal ${animal.noise}.` }} @let canRun = 'run' in animal; [class.run]="canRun">{{ `The animal runs in ${animal.run}.` }} @let canJump = 'jump' in animal; [class.jump]="canJump">{{ `The animal jumps in ${animal.jump}.` }} }

In this example, the results of the "in" keyword are used to show or hide the CSS classes. If the animal object has the swim property, the swim class will be applied to the paragraph element, and the text will be rendered goldenrod. If the animal object has the noise property, the noise class will render the text crimson. If the animal object has the run property, the text color is rebeccapurple. Finally, if the animal object has the jump property, the paragraph element has the jump class and fuchsia text color.

When the animal is a Dog, we will see

  • The animal swims in a swimming pool in goldenrod.
  • The animal barks in crimson, and
  • The animal runs on a beach in rebeccapurple.

Benefits

Supporting the in keyword in the template offers several advantages:

  • The template can check the presence of properties in an object.
  • The Angular expression will someday become a plain TypeScript expression.
  • The "in" keyword is evaluated to a boolean and can be displayed in expressions, enabled CSS classes, and tested in the new control flow.

Conclusion

Angular expressions are making strides toward being like plain TypeScript expressions. In Angular 19 and 20, templates can perform template strings, tagged template literals, exponential operators, and the "in" keyword in binary expressions.

Resources