Angular Basics

Explain the basic concepts of Angular, including components, modules, and services.

Angualr is a platform and framework for building single-page client applications using HTML and TypeScript. It is maintained by Google and a community of individuals and corporations.

Installation

To install Angular CLI, use the following command:

1
npm install -g @angular/cli

This command installs Angular CLI globally on your system, allowing you to create and manage Angular projects.

create a new Angular project:

1
ng new my-angular-app

This command creates a new directory called my-angular-app with all the necessary files and dependencies for an Angular application.

serve the application:

1
2
cd my-angular-app
ng serve

This command starts a local development server and opens the application in your default web browser. The application will be available at http://localhost:4200.

Component

Components are the main building blocks of Angular applications. Each component represents a part of a larger web page. Organizing an application into components helps provide structure to your project, clearly separating code into specific parts that are easy to maintain and grow over time.

To create a new component, use the following command:

1
ng generate component todo-list

This command creates a new directory called todo-list with four files:

  • todo-list.component.ts: The TypeScript file that contains the component’s logic.
  • todo-list.component.html: The HTML file that contains the component’s template.
  • todo-list.component.css: The CSS file that contains the component’s styles.
  • todo-list.component.spec.ts: The test file for the component.

todo-list.component.ts - This file contains the component’s logic and metadata. The @Component decorator is used to define the component’s metadata, including its selector, template URL, and style URL. The name of the component is TodoListComponent.

1
2
3
4
5
6
7
8
9
10
11
import { Component } from '@angular/core';

@Component({
selector: 'app-todo-list',
imports: [],
templateUrl: './todo-list.component.html',
styleUrl: './todo-list.component.css'
})
export class TodoListComponent {

}
  • selector is the name used to reference the component in HTML templates. In this case, add <app-todo-list></app-todo-list> to the HTML file where you want to use this component.
  • imports array is used to import other Angular modules or components that the component depends on. E.g FormsModule
  • templateUrl is the path to the HTML file that contains the component’s template. styleUrl is the path to the CSS file that contains the component’s styles.
  • styleUrl is an array of paths to the CSS files that contain the component’s styles. You can specify multiple stylesheets if needed.

Template

In Angular, a template is a chunk of HTML. Use special syntax within a template to leverage many of Angular’s features.

Text interpolation

Text interpolation is a way to display dynamic data in the template. It allows you to bind data from the component class to the HTML template using double curly braces {{ }}.

In the todo-list.component.ts file, add a property called title to the TodoListComponent class. This property will hold the title of the todo list.

1
title = 'Todo List';

In the todo-list.component.html file, use text interpolation to display the title in an <h1> element.

1
<h1>{{ title }}</h1>

When the component is rendered, the value of the title property will be displayed in the <h1> element.

Property binding

In Angular, you use property bindings to set values directly to the DOM representation of the element.

1
2
<!-- Bind the `disabled` property on the button element's DOM object -->
<button [disabled]="isFormValid">Save</button>

Two-way data binding

Two way binding is a shorthand to simultaneously bind a value into an element, while also giving that element the ability to propagate changes back through this binding.

The syntax for two-way binding is a combination of square brackets and parentheses, [()].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
imports: [FormsModule],
template: `
<main>
<h2>Hello {{ firstName }}!</h2>
<input type="text" [(ngModel)]="firstName" />
</main>
`
})
export class AppComponent {
firstName = 'Ada';
}

Event Listener

Angular supports defining event listeners on an element in your template by specifying the event name inside parentheses along with a statement that runs every time the event occurs.

In the todo-list.component.html file, use event binding to call the handleAddTodo method when the button is clicked.

1
2
<input type="text" [(ngModel)]="newTodo" placeholder="Add a new todo" />
<button (click)="handleAddTodo()">Add Todo</button>

In the todo-list.component.ts file, add a method called onAddTodo that will be called when the button is clicked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
selector: 'app-todo-list',
imports: [FormsModule],
templateUrl: './todo-list.component.html',
styleUrl: './todo-list.component.css'
})
export class TodoListComponent {
newTodo = '';

handleAddTodo = () => {
console.log('Add Todo');
console.log(this.newTodo);
}
}

When the button is clicked, the handleAddTodo method will be executed, and the message “Todo added!” will be logged to the console.

Control flow

Angular templates support control flow blocks that let you conditionally show, hide, and repeat elements.

@for

@for block block repeatedly renders content of a block for each item in a collection.

1
2
3
4
5
6
7
<ul>
@for (todo of todos; track todo.id) {
<li>{{ todo.title }}</li>
} @empty {
<div>No todos available</div>
}
</ul>

*ngFor

ngFor is a structural directive that allows you to iterate over a collection and create a template for each item in the collection.
You needc to import CommonModule in the component’s imports array to use ngFor.

1
2
3
<ul *ngFor="let todo of todos">
<li>{{ todo.title }}</li>
</ul>

@if

@if block block conditionally displays its content when its condition expression is truthy.

1
2
3
4
5
6
7
@if (a > b) {
{{a}} is greater than {{b}}
} @else if (b > a) {
{{a}} is less than {{b}}
} @else {
{{a}} is equal to {{b}}
}

*ngIf

*ngIf is a structural directive that conditionally includes or excludes a template based on the value of an expression.
You need to import CommonModule in the component’s imports array to use ngIf.

1
2
3
4
5
6
7
8
9
10
11
<div *ngIf="a > b; else elseBlock"> 
{{a}} is greater than {{b}}
</div>
<ng-template #elseBlock>
<div *ngIf="b > a">
{{a}} is less than {{b}}
</div>
<div *ngIf="a === b">
{{a}} is equal to {{b}}
</div>
</ng-template>

injectable service

Services are singleton objects that are instantiated only once during the lifetime of an application. They are used to share data and functionality across components. Services are typically used for tasks such as fetching data from a server, managing application state, or encapsulating business logic.

Services have @Injectable decorator, which marks a class as available to be provided and injected as a dependency. The @Injectable decorator is used to define a service in Angular.

1
2
3
4
5
6
7
import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root',
})
export class ToDoService {
}

HttpClient

HttpClient is a built-in Angular module that provides a simplified API for making HTTP requests. It is part of the @angular/common/http package and is designed to work with observables, making it easy to handle asynchronous data streams.

setup - configure HttpClient in app.config.ts

1
2
3
4
5
6
7
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
]
};

now you can use HttpClient by injecting it into your components or services.

use HttpCllient in a service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Todo } from '../todo-list/todo';

@Injectable({
providedIn: 'root',
})
export class ToDoService {
private apiUrl = 'https://jsonplaceholder.typicode.com/todos';
private http = inject(HttpClient);
constructor() {}

getTodos(): Observable<Todo[]> {
return this.http.get<Todo[]>(this.apiUrl);
}
}

From now on, you can use the ToDoService in your components to fetch data from the API. services can be injected into other services or components using the inject function.

1
todoService = inject(ToDoService);