Telerik blogs
AngularT2 Dark_1200x303

Today, we’ll look at basic syntax of Angular component templates so we’ll know how to create basic components that have some moving parts.

Angular is a framework that lets us create interactive web frontends for users. It is a component-based framework that lets us create frontend apps by composing components together. Each component has a template file or string, a component class and a style file.

We have to use the Angular template syntax to do things dynamically in templates. The syntax is mixed in with regular HTML to render dynamic content.

It comes with a few directives to let us do various things like conditionally render items and rendering items from iterable objects.

In this article, we’ll look at basic syntax of Angular component templates so we’ll know how to create basic components that have some moving parts.

Interpolation

One of the most basic things we want to do in our Angular components is to display values in the component class in the template. To do this, we use the interpolation syntax.

To render values from the component class, we put the this property in the component class in the curly braces.

In the template, we drop the this part. The variable will be assumed to be a property of this in the current component instance.

For instance, we write:

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  foo = 1;
  bar = "abc";
}

in app.components.tsx to add two instance variables into AppComponent, which are foo and bar.

Then in app.component.html, we write:

<div>
  <p>{{ foo }}</p>
  <p>{{ bar }}</p>
</div>

to render the value of foo and bar in AppComponent in the template.

We set templateUrl to "./app.component.html", so app.component.html in the same folder as app.components.tsx will be used to render the component’s output.

The interpolated values are put inside HTML tags so that the values will be rendered as text nodes in the HTML elements. In our example, we render the values of foo and bar in the p element.

The rendered result would be something like:

<div _ngcontent-wti-c18="">
  <p _ngcontent-wti-c18="">1</p>
  <p _ngcontent-wti-c18="">abc</p>
</div>

The attributes are automatically generated by Angular.

In addition to variables, we can put JavaScript expressions within the curly braces. For instance, we write:

app.component.tsx

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  a = 1;
  b = 2;
}

app.component.html

<div>
  <p>{{ a + b }}</p>
</div>

to define the instance variables a and b in the AppComponent class.

Then in app.component.html, we have {{ a + b }} which renders the sum of a and b. As a result, 3 is rendered.

The following expression syntaxes aren’t allowed in Angular templates:

  • new
  • ++ and --
  • +=, -= and other compound JavaScript operators
  • bitwise operators like | and &

Template Statements

In addition to rendering variable values and return values of expressions with interpolation, we can also add template statements into our templates. Statements are code that lets us do things like assigning values to variables and run methods in components from the template.

Examples of statements include function calls that are triggered from events and rendering items with various built-in directives.

Event Binding

We can also add template statements to respond to various events triggered by UI elements in the template.

For instance, we can call a method in our component class when a button is clicked by writing:

app.component.tsx

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  sayHello() {
    console.log("hello world");
  }
}

app.component.html

<div>
  <button type="button" (click)="sayHello()">hello</button>
</div>

In AppComponent, we add the sayHello method that logs 'hello world' into the console. And then in the app.component.html template file, we add a button that calls sayHello when we click on the button.

To call sayHello when the button is clicked, we add:

(click)="sayHello()"

to the button.

(click) listens for the click event when it’s emitted by the button. The click event is emitted when we click on the button.

And we add ="sayHello()" after (click) to call sayHello when the button is clicked.

Built-in Directives

Angular provides us with a few built-in directives that we can use in our templates.

We can use the *ngFor directive to render items in arrays onto the screen. And the *ngIf directive lets us render values conditionally onto the screen.

To use the *ngFor directive to render array items, we define a component instance variable that’s assigned to an array. Then in the template, we use the *ngFor directive to render the array by referencing it, assign the item being rendered to the loop variable, and then use the loop variable to render the item.

For instance, we write:

app.component.tsx

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  members = [
    { name: "jane" },
    { name: "james" },
    { name: "joe" },
    { name: "john" },
    { name: "joey" },
  ];
}

to define the members array that has five objects, each with the name property inside it.

Then we write:

app.component.html

<div>
  <p *ngFor="let member of members">{{ member.name }}</p>
</div>

to render values of members by using let member of members to assign the item in members being looped through to member.

And then we render member.name to render the name property’s value of each item.

We can also use the *ngIf directive to render items conditionally. The *ngIf directive is applied to an element or component to make it attach to the DOM only if the value we assign to it is truthy.

For instance, we write:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  show: boolean = false;
}

to define the show boolean instance variable in AppComponent. And we set its initial value to false.

Then in the template, we write:

app.component.html

<div>
  <button (click)="show = !show">toggle</button>
  <p *ngIf="show">hello world</p>
</div>

to add a button that toggles the value of show when we click the button with:

(click)="show = !show">

Then we add the *ngIf directive to the p element and assign its value to show so that the p element is only added to the DOM and rendered when show is true.

As a result, when we click on the toggle button, “hello world” will toggle on and off.

Pipes

We can use pipes to transform values that are returned by template expressions to the values we want to display. They take data and we return something derived from the data.

Angular comes with a few built-in pipes. They include:

  • DatePipe – formats a date according to the given locale
  • UpperCasePipe – formats text into upper case
  • LowerCasePipe – formats text into lower case
  • CurrencyPipe – formats text into a currency string according to the given locale
  • DecimalPipe – formats number into a string with decimal point according to the given locale
  • PercentPipe – formats a number into a percentage string

For instance, we can use them by writing:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  date: Date = new Date();
  str: string = "Foo";
  num: number = 123;
}

We add the date, str and num AppComponent instance variables that we want to format with the pipes in our template.

Then in app.component.html, we write:

<div>
  <p>{{ date | date }}</p>
  <p>{{ str | uppercase }}</p>
  <p>{{ str | lowercase }}</p>
  <p>{{ num | number }}</p>
  <p>{{ num | percent }}</p>
</div>

to format the date, str and num variables with the pipes.

To use the pipes, we add the pipe name after the “|” symbol. It returns the value that’s displayed on the screen and leaves the variables as is.

As a result, we get something like:

Apr 20, 2022

FOO

foo

123

12,300%

displayed on the screen.

We can pass arguments to pipes if they accept them. To pass arguments into pipes, we add the arguments after the pipe name and the colon.

For instance, we write:

app.component.tsx

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  date: Date = new Date();
}

app.component.html

<div>
  <p>{{ date | date: "MM/dd/yy" }}</p>
</div>

to add the date instance variable into AppComponent.

Then we render the value in the template using the date pipe with the "MM/dd/yy" argument. The date rendered will then have the month/day/year format instead of the default format.

And we get something like:

04/20/22

Property Binding

Another useful feature of Angular component templates is the ability to set attributes dynamically. To do this, we use the property binding feature.

Angular comes with a special syntax for binding properties to values in the template. We put the attribute name in the square brackets and then set it to an expression.

For instance, we write:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  itemImageUrl: string = "https://picsum.photos/200/300";
}

app.component.html

<div>
  <img alt="picture" [src]="itemImageUrl" />
</div>

to define the itemImageUrl string instance variable in AppComponent.

Then we add the img element in our template and set the src attribute of the img element to the value of the itemImageUrl string.

Since src is surrounded by square brackets, the value of itemImageUrl in AppComponent will be used as the value of the src attribute of the img element. And the picture at the URL is rendered.

We can put JavaScript expressions in place of a variable on the right hand side of the property binding.

For instance, we write:

app.component.html

<div>
  <table>
    <tbody>
      <tr>
        <td [colSpan]="1 + 1" style="background-color: yellow;">2 cols</td>
      </tr>
      <tr>
        <td>1 col</td>
        <td>1 col</td>
      </tr>
    </tbody>
  </table>
</div>

to add a table with a td that spans two columns with:

<td [colSpan]="1 + 1" style="background-color: yellow;">2 cols</td>

We set [colSpan] to 1 + 1 to use the returned value of the expression as the value of the colSpan attribute of the td element.

Attribute, Class and Style Bindings

Closely related features of property binding are attribute, class and style bindings. We use attribute binding to bind to any attribute.

For instance, we can rewrite the previous example to:

<div>
  <table>
    <tbody>
      <tr>
        <td [attr.colspan]="1 + 1" style="background-color: yellow">2 cols</td>
      </tr>
      <tr>
        <td>1 col</td>
        <td>1 col</td>
      </tr>
    </tbody>
  </table>
</div>

to set the colSpan attribute to the return value of 1 + 1.

We replace colspan with attr.colspan and they both do the same thing.

Rendering dynamic styles is something that’s commonly done in Angular templates. And we can do that by setting the class or style attribute dynamically.

For instance, we write:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  green: boolean = true;
}

app.component.html

<div>
  <button (click)="green = !green">toggle</button>
  <p [class.green]="green" [class.red]="!green">hello world</p>
</div>

app.component.css

.green {
  color: green;
}

.red {
  color: red;
}

to add the green boolean variable. And we use that as the flag to apply the green class to the p element if green is true. Likewise, we apply the red class to the p element if the green variable is false.

We use the button to toggle the green variable between true and false when we click on the button. The app.component.css file has the styles for either class.

We can rewrite the example above with style bindings. To do this, we remove the code in app.component.css. Then we replace the code in app.component.html with:

<div>
  <button (click)="green = !green">toggle</button>
  <p [style.color]="green ? 'green' : 'red'">hello world</p>
</div>

And we leave the code in app.component.ts as is.

We set the value of the color style dynamically with:

[style.color]="green ? 'green' : 'red'"

If green is true, we set the color CSS property of the p element to 'green'. Otherwise, we set it to 'red'.

Conclusion

Angular is a framework that lets us create interactive web frontends for users. The core feature of the framework is the ability for us to compose components to create a frontend app.

Each component has a template file or string, a component class and a style file.

To render content dynamically, we use regular HTML in addition to the special syntax provided by Angular to let us render elements dynamically.

Also, it comes with a few directives to let us do various things like conditionally render items and render items from iterable objects.

Pipes are useful for formatting values in templates in an immutable fashion.


About the Author

John Au-Yeung

John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.

Related Posts