Gentle Introduction to Angular

Understand the Angular framework and see how code is written in it.

Understanding the Angular code

As I said before, this is not a course on Angular. However, there are some patterns and syntax idioms that you should become familiar with before you get into the code. I like to think of them as Angularisms (yes, I just made up that word).

To work through the example in this lesson, click on the Run button on the coding playground below. Your Angular application will start installing required packages and will compile. As soon as it is done, you can see the output window or click on the link to see your Angular application.

You can also make changes to the code and click the Run button again to see the effects.

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "types": [
      "jasmine",
      "node"
    ]
  },
  "files": [
    "test.ts",
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}
Angular application

Let’s start understanding the application code. You can see the file app.component.ts in src > app folder (also shown below).

import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
}

Let’s start by discussing Angular’s concept of separation of concerns. In Angular, UI functionality is encapsulated in components. A component can represent anything from a piece of text, a button, a form, or even an entire page. Components can contain other components, and they can communicate with each other through well-defined interfaces.

You specify that a TypeScript class is a component using the @component decorator. Decorators provide additional information by annotating or modifying classes or class members.

In this case, the component decorator provides additional metadata to Angular about how the class will behave. The selector attribute tells Angular to expose this component using the html tag <my-app>.

The templateUrl attribute indicates that the HTML markup can be found in the file specified, app.component.html.

Likewise, with the styleUrls. Notice that this value is an array, which means you can provide more than one CSS file.

The executable portion of the component code is found inside the class definition. This one contains a single line of code, meaning it is not doing much.

This is what you mean by a “separation of concerns.” The code, markup, and styles are all separated from one another.

Take a look at the markup, which is found in the template file, app.component.html. This file is pure HTML containing the content.

<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>

Notice the first line contains a custom HTML tag, <hello>. That is defined in hello.component.ts, which you will review shortly.

Inside of that tag is an attribute called name, set to the value {{ name }}. This is an Angular “one-way” binding expression. During the page rendering phase, Angular sees that expression and knows to set the value of the name attribute to the run-time value of the variable name on the component. It would probably be less confusing if they used a different variable name.

Return to the component code and change the name variable. I changed mine to look like this:

export class AppComponent {
name = 'Mike';
}

After pressing Run on the above coding playground, look at the result that appears in the output tab. The value you provided should be displayed instead of the original value.

Open up the file hello.component.ts and look at its implementation. The first thing you may notice is that all of its markup and styling is defined in the same file.

import { Component, Input } from '@angular/core';
@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
@Input() name: string;
}

Instead of providing a templateUrl and styleUrls, both of them are provided directly in the file. It is worth pointing out that this is still a form of separation of concerns. The HTML markup is clearly separated from the styling and component code.

Personally, I would not recommend you do this, except in the simplest of components. That said, there are many proponents of keeping all of your component code in one file. It is often best to adopt a general rule of either “always” or “never” doing this. Find your own balance — one that allows your style to remain organized but flexible.

Inside the component code is a single line of code.

@Input() name: string;

The @Input decorator specifies that name is a string attribute that can be provided in the markup of any client that uses this component.

Component reuse

The real power behind this is that you can reuse the component anywhere, simply replacing its name attribute, and it will render consistently.

Back in app.component.html, make a few copies of the <hello> tag and provide different names. Perhaps something like the following:

<hello name="{{ name }}"></hello>
<hello name="Greg"></hello>
<hello name="Jonathan"></hello>
<hello name="Neil"></hello>
<p>
Start editing to see some magic happen :)
</p>

Now it looks like this, and I do not have to be concerned with how the <hello> tag works behind the scenes. I can simply reuse it.

The ngFor directive

But what if you have a bunch of names? Change the name variable on the component and make it an array called names.

export class AppComponent {
names = ['Mike', 'Greg', 'Jonathan', 'Neil'];
}

The cool thing about reusing components this way is that you do not have to change the hello component at all. You simply need to change the calling code to use ngFor, an Angular directive used to create multiple instances of the HelloComponent based on the number of elements in the referenced array.

You use an ngFor by providing it as an attribute to the element you want replicated. The value inside the quotes is the looping expression. It consists of the keyword let followed by the variable name to be used inside the element and any of its children, the keyword of, and the name of the array on the component to loop over.

<hello *ngFor="let name of names" name="{{name}}"></hello>

The asterisk, which is required, is an indication to Angular that this directive will manipulate the page’s document object model, or DOM, in some way.

Attribute binding

There is another Binding syntax that works with HTML attributes. If you want to set the value of an attribute to a value on your component, use square brackets around the attribute name.

<hello *ngFor="let name of names" [name]="name"></hello>

Here, name, in square brackets, refers to the HTML attribute of the custom component. The name in quotes is the name of the variable in the ngFor expression. When you are binding to an HTML attribute, this is my preferred method because you can run just about any code you want inside of those quotes.

HTML event binding

You can also bind to HTML events. Any event can become a trigger to execute a function on the component. The simplest way to illustrate that is to create a button and provide a click handler.

You do that by surrounding the event name (in this case, click) with parenthesis. Then inside the quotes, call the component function you want to execute.

You can pass parameters to the function, which is often the case when creating an event binding inside an *ngFor, passing the current looping variable to the event handler.

In this case, just call toggle().

<button (click)="toggle()">Click Me</button>

Back inside the component, you need to implement the toggle function. Add this code inside the app component, right after the names array (inside the export class AppComponent block).

isToggled = false;
toggle() {
this.isToggled = !this.isToggled;
}

Now when you click the toggle button, the value of the isToggled variable will flip between true and false.

The ngIf directive

The isToggled variable is useless until you do something with it. Add a new line inside the app component template file.

In this case, add a paragraph tag, give it an ngIf directive, and set it to isToggled.

<p *ngIf="isToggled">
I am toggled on!!!
</p>

The ngIf directive will conditionally render the HTML tag if the value inside the quotes evaluates to a truthy value. Notice that ngIf also requires an asterisk because it modifies the DOM.

Now as you click the button, that paragraph will appear and disappear.

Those are the basics you need to know to work with Ionic and Angular. Next, you will go ahead and create an Ionic app.

Quiz

1

What is Angular?

A)

A library for creating websites

B)

A front-end web application framework based on TypeScript

C)

It is a library used for styling and adding specific features to the webpage.

D)

It is a service that connects the Ionic frontend with the backend.

Question 1 of 40 attempted