A great feature of Angular is the capability to add JavaScript-like expressions inside an HTML template. Angular evaluates expressions and then can dynamically add the results to a web page. Expressions are linked to a component, and you can have an expression that utilizes values in the component, and its value can change as the model changes.
Using expressions is the simplest way to represent data from a component in an Angular view. Expressions are encapsulated blocks of code inside brackets, like this:
{{expression}}
The Angular compiler compiles an expression into HTML elements so that the results of the expression are displayed. For example, look at the following expressions:
{{1+5}} {{'One' + 'Two'}}
Based on these expressions, the web page displays the following values:
6 OneTwo
Expressions are bound to the data model, which provides two huge benefits. First, you can use the property names and functions that are defined in the component inside your expressions. Second, because the expressions are bound to the component, when data in the component changes, so do the expressions. For example, say that a component contains the following values:
name: string='Brad'; score: number=95;
You can directly reference the name
and score
values in the template expressions, as shown here:
Name: {{name}} Score: {{score}} Adjusted: {{score+5}}
Angular expressions are similar to TypeScript/JavaScript expressions in several ways, but they differ in these ways:
Attribute evaluation: Property names are evaluated against the component model instead of against the global JavaScript namespace.
More forgiving: Expressions do not throw exceptions when they encounter undefined or null variable types; instead, they treat them as having no value.
No flow control: Expressions do not allow the following:
Assignments (for example, =, +=, -=
)
The new
operator
Conditionals
Loops
Increment and decrement operators (++
and --
)
Also, you cannot throw an error inside an expression
Angular evaluates as expressions the strings used to define the values of directives. This means you can include expression-type syntax within a definition. For example, when you set the value of the ng-click
directive in the template, you specify an expression. Inside that expression, you can reference a component variable and use other expression syntax, as shown here:
<span ng-click="myFunction()"></span> <span ng-click="myFunction(var, 'stringParameter')"></span> <span ng-click="myFunction(5*var)"></span>
Because the Angular template expressions have access to the component, you can also make changes to the component inside the Angular expression. For example, this (click)
directive changes the value of msg
inside the component model:
<span (click)="msg='clicked'"></span>
The following sections take you through some examples of using the expression capability in Angular.
In this section, you get a chance to see how Angular expressions handle rendering of strings and numbers. This example illustrates how Angular evaluates expressions that contain strings and numbers as well as basic mathematical operators.
Listing 23.1 shows an Angular component. This component has a template that contains several types of expressions wrapped in double curly brackets ({{}}
). Some of the expressions are just numbers or strings, some include the +
operation to combine strings and/or numbers, and one applies a ===
operator to compare two numbers.
Figure 23.1 shows the rendered web page. Note that numbers and strings are rendered directly to the final view. Adding strings and numbers together enables you to build text strings that are rendered to the view. Also note that using a comparison operator renders the word true
or false
to the view.
Listing 23.1 basicExpressions.component.ts
: Basic Strings and Numbers with Simple Math Operations in an Angular Template
01 import { Component } from '@angular/core'; 02 03 @Component({ 04 selector: 'app-root', 05 template: ` 06 <h1>Expressions</h1> 07 Number:<br> 08 {{5}}<hr> 09 String:<br> 10 {{'My String'}}<hr> 11 Adding two strings together:<br> 12 {{'String1' + ' ' + 'String2'}}<hr> 13 Adding two numbers together:<br> 14 {{5+5}}<hr> 15 Adding strings and numbers together:<br> 16 {{5 + '+' + 5 + '='}}{{5+5}}<hr> 17 Comparing two numbers with each other:<br> 18 {{5===5}}<hr> 19 `, 20 }) 21 export class AppComponent {}
Figure 23.1 Using Angular expressions that contain strings, numbers, and basic math operations
Component
Class in ExpressionsNow that you have seen some basic Angular expressions, let's take a look at how to interact with the Component
class inside Angular expressions. In the previous example, all the input for the expressions came from explicit strings or numbers. This section illustrates the true power of Angular expressions that come from interacting with the model.
Listing 23.2 shows an Angular component file that applies Angular expressions that use values from the Component
class to render text to the screen as well as act as parameters to functions. Note that the variable names in the Component
class can be used directly in the expressions. For example, the expression in line 9 creates a string based on the values of the speed
and vehicle
variables.
Figure 23.2 shows the rendered web page, based on the expressions. Note that when the links of the page are clicked, the resulting function calls adjust the Component
class variables, which change how the previously discussed expressions are rendered.
Listing 23.2 classExpressions.component.ts
: An Angular Application that Uses Expressions to Interact with Data from the Component
Class
01 import { Component } from '@angular/core'; 02 03 @Component({ 04 selector: 'app-root', 05 template: ` 06 Directly accessing variables in the component:<br> 07 {{speed}} {{vehicle}}<hr> 08 Adding variables in the component:<br> 09 {{speed + ' ' + vehicle}}<hr> 10 Calling function in the component:<br> 11 {{lower(speed)}} {{upper('Jeep')}}<hr> 12 <a (click)="setValues('Fast', newVehicle)"> 13 Click to change to Fast {{newVehicle}}</a><hr> 14 <a (click)="setValues(newSpeed, 'Rocket')"> 15 Click to change to {{newSpeed}} Rocket</a><hr> 16 <a (click)="vehicle='Car'"> 17 Click to change the vehicle to a Car</a><hr> 18 <a (click)="vehicle='Enhanced ' + vehicle"> 19 Click to Enhance Vehicle</a><hr> 20 `, 21 styles:[` 22 a{color: blue; text-decoration: underline; cursor: pointer} 23 `] 24 }) 25 export class AppComponent { 26 speed = 'Slow'; 27 vehicle = 'Train'; 28 newSpeed = 'Hypersonic'; 29 newVehicle = 'Plane'; 30 upper = function(str: any){ 31 str = str.toUpperCase(); 32 return str; 33 } 34 lower = function(str: any){ 35 return str.toLowerCase(); 36 } 37 setValues = function(speed: any, vehicle: any){ 38 this.speed = speed; 39 this.vehicle = vehicle; 40 } 41 }
This section takes a look at some additional TypeScript interactions within the Component
class. As described previously, much of the TypeScript functionality is supported in Angular expressions. To illustrate this better, this example shows some array manipulation and uses the TypeScript Math
object within expressions.
Listing 23.3 implements an Angular component that uses Angular expressions that take advantage of push()
and shift()
to display the arrays, show the array length, and manipulate the array elements. Note that with Math
added to the Component
class, you are able to use TypeScript Math
operations directly in the expressions in lines 12 and 21.
Figure 23.3 shows the Angular web page rendered. Notice that as the links are clicked, the arrays are adjusted and the expressions are reevaluated.
Listing 23.3 typescriptExpressions.component.ts
: An Angular Component that Uses Expressions Containing Arrays and Math
01 import { Component } from '@angular/core'; 02 03 @Component({ 04 selector: 'app-root', 05 template: ` 06 <h1>Expressions</h1> 07 Array:<br> 08 {{myArr.join(', ')}}<br/> 09 <hr> 10 Elements removed from array:<br> 11 {{removedArr.join(', ')}}<hr> 12 <a (click)="myArr.push(myMath.floor(myMath.random()*100+1))"> 13 Click to append a value to the array 14 </a><hr> 15 <a (click)="removedArr.push(myArr.shift())"> 16 Click to remove the first value from the array 17 </a><hr> 18 Size of Array:<br> 19 {{myArr.length}}<hr> 20 Max number removed from the array:<br> 21 {{myMath.max.apply(myMath, removedArr)}}<hr> 22 `, 23 styles: [` 24 a { 25 color: blue; 26 cursor: pointer; 27 } 28 `], 29 }) 30 export class AppComponent { 31 myMath = Math; 32 myArr: number[] = [1]; 33 removedArr: number[] = [0]; 34 }
Figure 23.3 Using Angular expressions that apply TypeScript array and Math
operations to interact with scope data
A great feature of Angular is the capability to implement pipes. A pipe is a type of operator that hooks into the expression parser and modifies the results of the expression for display in a view—for example, to format time or currency values.
You implement pipes inside expressions, using the following syntax:
{{expression
|pipe
}}
If you chain multiple pipes together, they are executed in the order in which you specify them:
{{expression
|pipe
|pipe
}}
Some filters allow you to provide input in the form of function parameters. You add these parameters by using the following syntax:
{{expression
|pipe
:parameter1
:parameter2
}}
Angular provides several types of pipes that enable you to easily format strings, objects, and arrays in component templates. Table 23.1 lists the built-in pipes provided with Angular.
Table 23.1 Pipes That Modify Expressions in Angular Component Templates
This section shows how the built-in Angular pipes handle the transformation of data in Angular expressions. The purpose of this example is to show how pipes transform the data provided.
Listing 23.4 shows the Angular component with a template that contains several examples of built-in pipes wrapped in {{}}
brackets. The Component
class contains data for some of the pipes to use.
Figure 23.4 shows the rendered application with the transformed data.
Listing 23.4 builtInPipes.component.ts
: An Angular Component That Contains an Example of Built-in Pipes
01 import { Component } from '@angular/core'; 02 03 @Component({ 04 selector: 'app-root', 05 template: ` 06 Uppercase: {{"Brendan" | uppercase }}<br> 07 Lowercase: {{"HELLO WORLD" | lowercase}}<br> 08 Date: {{ today | date:'yMMMMEEEEhmsz'}}<br> 09 Date: {{today | date:'mediumDate'}}<br> 10 Date: {{today | date: 'shortTime'}}<br> 11 Number: {{3.1415927 | number:'2.1-5'}}<br> 12 Number: {{28 | number:'2.3'}}<br> 13 Currency: {{125.257 | currency:'USD':true: '1.2-2'}}<br> 14 Currency: {{2158.925 | currency}}<br> 15 Json: {{jsonObject | json}}<br> 16 PercentPipe: {{.8888 | percent: '2.2'}}<br> 17 SlicePipe: {{"hello world" | slice:0:8}}<br> 18 SlicePipe: {{days | slice:1:6}}<br> 19 legen... {{wait | async}} {{dairy | async}} 20 ` 21 }) 22 export class AppComponent { 23 today = Date.now(); 24 jsonObject = [{title: "mytitle"}, {title: "Programmer"}]; 25 days=['Sunday', 'Monday', 'Tuesday', 'Wednesday', 26 'Thursday', 'Friday', 'Saturday']; 27 wait = new Promise<string>((res, err) => { 28 setTimeout(function () { 29 res('wait for it...'); 30 },1000); 31 }); 32 dairy = new Promise<string>((res, err) => { 33 setTimeout(function() { 34 res('dairy'); 35 },2000) 36 }) 37 }
Angular enables you to create your own custom pipes and then use them within expressions and services as if they were built-in pipes. Angular provides the @pipe
decorator to create a pipe and register it with the dependency injector server.
The @pipe
decorator takes in metadata, just as an Angular component does. The metadata options are name
and pure
. The name
metadata works like the selector of a component: It tells Angular where you want to use the pipe. The pure
metadata tells the pipe how to handle change detection. A pure
pipe updates when there is a change to the input value or an object reference. An impure
pipe can update whenever there is an event, such as a keystroke, mouse click, or mouse movement. The following example demonstrates a sample pipe and its syntax:
@Pipe({ name: 'example', Pure: true })
The pipe
class works much the same as the Component
class, in that it is where the logic of the pipe resides. However, the logic needs to be within a Transform
method, which tells the pipe how to transform whatever is to the left of the pipe symbol (|
). Review the following example:
Export class customPipe{ Transform(parameter1:string, parameter2:number) : string { myStr = "logic goes in here"; return myStr; } }
This section shows how to build a custom pipe that filters out select words from a string. The purpose of this example is to show you how to create and apply a custom pipe that can transform data.
Listing 23.5 shows an Angular pipe with the name
metadata censor
. The export
class contains the Transform
method, which replaces certain words with a different string and then returns the transformed string.
Listing 23.6 shows an Angular component which contains template that uses the custom pipe, as well as the pipe
metadata to import the pipe. Notice that on line 6, there is the expression that you use to implement the pipe. The pipe takes in a string as an argument and replaces the word with it.
Figure 23.5 shows the rendered application, using the custom pipe.
Listing 23.5 custom.pipe.ts
: An Angular Pipe That Replaces Certain Words in a String
01 import {Pipe} from '@angular/core'; 02 03 @Pipe({name: 'censor'}) 04 export class censorPipe{ 05 transform(input:string, replacement:string) : string { 06 var cWords = ["bad", "rotten", "terrible"]; 07 var out = input; 08 for(var i=0; i<cWords.length; i++){ 09 out = out.replace(cWords[i], replacement); 10 } 11 return out 12 } 13 }
Listing 23.6 customPipes.component.ts
: An Angular Component That Imports and Uses a Custom Pipe
01 import { Component } from '@angular/core'; 02 03 @Component({ 04 selector: 'app-root', 05 template: ` 06 {{phrase | censor:"*****"}} 07 ` 08 }) 09 export class AppComponent { 10 phrase:string="This bad phrase is rotten "; 11 }
Angular comes with powerful built-in expressions and pipes and provides the option to create custom pipes. This chapter discusses the available built-in expressions and pipes and how to implement them. It also discusses how to build and implement a custom pipe. Expressions are bits of TypeScript code contained within {{}}
, and pipes are able to manipulate those expressions. Expressions have access to information within the Component
class and can render class variables to the view.
In the next chapter you will learn about databinding. You will learn about how it links data together and expand on the many different types of databinding.
52.14.240.252