learn-angular v2.5.0
Learn Angular
This repository contains a list of resources to learn Angular. It includes tutorials, articles, videos, books, and other resources to help you learn Angular from scratch.
Table of Contents
- Introduction
- Roadmap
- Configuration
- Components
- Data Binding
- Directives
- Pipes
- Decorators
- Life Cycle Hooks
- Forms
- Services
- Routing
- Lazy Loading
- HTTP Client
- Destroy Ref
- Http
- Module
- Router
- Route Parameter
- Observables
- Unsubscribe
- Renderer2
- JIT
- AOT
- Deferrable Views
- Meta Tags
- Security
- Preventing cross-site scripting (XSS)
- Angular's cross-site scripting security model
- Preventing cross-site scripting (XSS)
- Angular's cross-site scripting security model
- Sanitization and security contexts
- Sanitization example
- Direct use of the DOM APIs and explicit sanitization calls
- Trusting safe values
- Content security policy
- Enforcing Trusted Types
- Use the AOT template compiler
- Server-side XSS protection
- HTTP-level vulnerabilities
- Cross-site request forgery
- HttpClient XSRF/CSRF security
- Configure custom cookie/header names
- Disabling XSRF protection
- Cross-site script inclusion (XSSI)
- Auditing Angular applications
- Standalone Components
- Angular Signals
- Angular Animations
- Angular Universal
- Bootstrap
- Angular Material
- Tailwind CSS
- PrimeNG
- PWA
- CLI Commands
- Version compatibility
- Imports
- TypeScript
- RxJS
- Learn From GitHub Repositories
- Learn From Websites
- Learn From Books
- Learn From YouTube Channels
- Learn More From Blogs Sites
- List of Online Editors/Compiler for Angular
- List of Twitter Users to Follow
- List of LinkedIn Users to Follow
- List of Discord Servers to Join
Introduction
Angular is a popular open-source framework by Google for building single-page and dynamic web applications. It offers tools and libraries for components, services, forms, routing, and HTTP client, all built with TypeScript. Angular is known for its performance, scalability, and developer productivity.
Features of Angular
- Component-Based Architecture: Reusable, self-contained units of code that define the UI and behavior of a part of the application.
- Two-Way Data Binding: Automatic synchronization of data between the model and the view.
- Dependency Injection: Provides components with the services they need for better modularity and testability.
- Routing: Powerful system for navigation between different views, supporting deep linking, lazy loading, and route guards.
- Forms: Tools for template-driven and reactive forms, based on a model-driven approach.
- HTTP Client: Simple API for making HTTP requests and handling responses.
- Observables: Handles asynchronous operations and event handling.
- TypeScript: Superset of JavaScript with static typing, better tooling, error checking, and code completion.
- Performance: Optimized for performance with virtual DOM, lazy loading, tree shaking, and ahead-of-time compilation.
- Mobile Support: Tools for building responsive, touch-friendly mobile applications, including PWAs.
- SEO Friendly: Tools for server-side rendering, pre-rendering, and meta tags to improve search engine visibility.
- Community Support: Large, active community providing support and sharing knowledge.
Difference between AngularJS vs Angular
AngularJS | Angular |
---|---|
Based on MVC Architecture | Based on Components |
Uses JavaScript to build the application | Uses TypeScript to build the application |
No Mobile Support | Mobile supports |
Run on only client-side | Runs on both client-side as well as server-side |
CLI not present | CLI present |
No SEO Friendly | Seo Friendly |
Performance is slow | Performance is fast |
Angular vs React
Angular: A full-fledged framework by Google for building web applications. It includes features like two-way data binding, routing, forms, and HTTP client. Ideal for large, complex applications needing a complete solution.
React: A JavaScript library by Facebook focused on building user interfaces. It provides a simple, declarative way to build UI components. Suitable for small to medium-sized applications requiring flexibility and customization.
Comparison: Angular offers a complete solution with built-in features, while React focuses on the view layer, allowing developers to choose additional tools and libraries.
When to use Angular: Best for large, complex applications needing integrated tools and scalability.
When to use React: Best for small to medium-sized applications needing flexibility and a focus on the UI.
SPA
SPA (Single Page Application) is a web application that dynamically rewrites the current page instead of loading entire new pages from the server, providing a fluid and responsive user experience.
Advantages of SPA
- Faster Load Times: Loads the initial page once; subsequent interactions update dynamically.
- Better User Experience: No full page reloads, allowing faster navigation and smoother transitions.
- Reduced Server Load: Less server load as only necessary data is fetched.
- Improved SEO: Optimizable for search engines with server-side rendering and meta tags.
- Offline Support: Accessible offline using service workers and caching.
- Mobile Support: Optimized for mobile with responsive design and touch gestures.
- Scalability: Handles many users and interactions with performance optimizations like lazy loading.
Roadmap
Configuration
Prerequisites
- Node.js
- NPM
- Angular CLI
Installation
Install the Angular CLI globally:
npm install -g @angular/cli
If you have already installed the Angular CLI, you can update it to the latest version using the following command:
npm install -g @angular/cli@latest
Check version
ng version
Create a new Angular project: (Replace [PROJECT NAME]
with your project name)
# with standalone component
ng new [PROJECT NAME]
# without standalone component
ng new [PROJECT NAME] --standalone=false
Note: In version v17 and later, the standalone component is default enabled. In version v16 and earlier, the standalone component is disabled by default. You can enable or disable the standalone component using the --standalone
flag. (In this repository, an example repository is created with the latest version of Angular.)
Navigate to the project directory:
cd [PROJECT NAME]
Run the application:
ng serve
Open the browser and navigate to http://localhost:4200/
.
Components
Component is the main building block of an Angular Application. It is a TypeScript class that interacts with the HTML template and provides the data and logic to the view.
Three main building blocks
There are three main building blocks of an Angular component:
- Template
- Class
- Metadata
Template - Defines the layout and content of the View.
Class - Class provides the data & logic to the View.
MetaData - Metadata Provides additional information about the component to the Angular.
Component metadata properties
There are several properties that can be defined in the component metadata:
- Selector
- Providers
- Styles
- StyleUrls
- Template
- TemplateUrl
Selector - Defines the element name or CSS selector that identifies the component in the HTML template.
Providers - Defines the providers of the component's dependencies.
styles - Defines the inline styles for the component.
styleUrls - Defines an array of URLs of the stylesheets for the component.
template - Defines the HTML template for the component.
templateUrl - Defines the URL of the HTML template for the component.
Component Creation
Using Angular CLI
ng generate component [component-name]
Manual Creation
Step 1 - Create a new folder for the component inside the src/app
folder.
src/app/[component-name]
Step 2 - Create a new TypeScript file for the component inside the new folder.
src/app/[component-name]/[component-name].component.ts
Step 3 - Create a new HTML file for the component inside the new folder.
src/app/[component-name]/[component-name].component.html
Step 4 - Create a new CSS file for the component inside the new folder.
src/app/[component-name]/[component-name].component.css
Step 5 - Import the Component class from the @angular/core
module.
import { Component } from '@angular/core';
Step 6 - Decorate the class with the @Component
decorator.
@Component({
selector: 'app-[component-name]',
standalone: true,
templateUrl: './[component-name].component.html',
styleUrls: ['./[component-name].component.css']
})
If you want to create a standalone component, set the standalone
property to true
. If you want to create a non-standalone component, set the standalone
property to false
. The standalone component is enabled by default in Angular v17 and later.
Step 7 - Define the selector, template, and styles for the component.
selector - The selector for the component.
templateUrl - The URL of the HTML template for the component.
styleUrls - An array of URLs of the stylesheets for the component.
Step 8 - Export the class.
export class [ComponentName]Component {
}
Step 9 - Import the component class in the app.module.ts
file.
import { [ComponentName]Component } from './[component-name]/[component-name].component';
Step 10 - Add the component to the declarations
array in the @NgModule
decorator.
declarations: [
AppComponent,
[ComponentName]Component
]
If you created a standalone component, app.module.ts
file is not required. You can import the component in the app.component.ts
file.
as shown below.
import { [ComponentName]Component } from './[component-name]/[component-name].component';
@Component({
selector: 'app-root',
standalone: true,
imports: [[ComponentName]Component],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'app';
}
Step 11 - Use the component selector in the HTML template.
<app-[component-name]></app-[component-name]>
Step 12 - Run the application using the ng serve
command.
ng serve
Example
Creating the component files (Version 16 and earlier) -
//test-component.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'test-component',
templateUrl: './component.component.html',
styleUrls: ['./component.component.css']
})
export class TestComponent {
}
<!--component.component.html-->
<h1>Test Component</h1>
/*component.component.css*/
h1 {
color: red;
}
Creating the component files (Version 17 and later) -
//test-component.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-test-component',
standalone: true,
templateUrl: './test-component.component.html',
styleUrls: ['./test-component.component.css']
})
export class TestComponent {}
You can create a standalone component by setting the standalone
property to true
. The standalone component is enabled by default in Angular v17 and later. You can disable the standalone component by setting the standalone
property to false
in the @Component
decorator of the component. If you disable the standalone component, you need to import the component in the app.module.ts
file. If you created a non-standalone component, you will see no standalone property in the @Component
decorator.
<!--test-component.component.html-->
<h1>Test Component</h1>
/*test-component.component.css*/
h1 {
color: red;
}
Importing the component in the app.module.ts file (Version 16 and earlier) -
//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TestComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Importing the component in the app.module.ts file (Version 17 and later without standalone component) -
//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TestComponent } from './test-component/test-component.component';
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In version 17 and later, the standalone component is enabled by default. You can disable the standalone component by setting the standalone
property to false
. Inside app folder, app.config.ts
file is created by default.
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
],
};
You can import the component in the app.component.ts
file and use the component selector in the HTML template.
//app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { TestComponent } from './test-component/test-component.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [TestComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'app';
}
<!--app.component.html-->
<app-test-component></app-test-component>
Creating the inline Template & StyleUrls -
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<h1> {{title}} works </h1>',
styles: ['h1 { font-weight: bold; }']
})
export class AppComponent {
title = 'app';
}
Scope
In Angular, the scope of a variable determines where it can be accessed:
- Global Scope: Accessible anywhere in the application.
- Local Scope: Accessible only within a specific function or block.
- Component Scope: Accessible within a component and its child components.
Global Scope
Accessible from anywhere in the application; defined outside any function or block.
Example :
// Global Scope
let globalVariable = 'Global Variable';
function testFunction() {
console.log(globalVariable); // Output: Global Variable
}
testFunction();
Example in Angular :
import { Component } from '@angular/core';
// Global Scope
let globalVariable = 'Global Variable';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = globalVariable;
}
<!--app.component.html-->
<h1>{{ title }}</h1>
Local Scope
Accessible only within the function or block where defined.
Example :
function testFunction() {
// Local Scope
let localVariable = 'Local Variable';
console.log(localVariable); // Output: Local Variable
}
testFunction();
console.log(localVariable); // Error: localVariable is not defined
Example in Angular :
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
testFunction() {
// Local Scope
let localVariable = 'Local Variable';
console.log(localVariable); // Output: Local Variable
}
}
<!--app.component.html-->
<button (click)="testFunction()">Test Function</button>
Component Scope
Accessible within the component and its children.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// Component Scope
title = 'app';
}
<!--app.component.html-->
<h1>{{ title }}</h1>
View Encapsulation
Controls how styles are applied to components. By default, Angular uses Emulated View Encapsulation, scoping styles to the component.
Emulated View Encapsulation
Default mode in Angular, emulating shadow DOM to scope styles to the component.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.Emulated
})
export class AppComponent {
title = 'app';
}
Shadow DOM View Encapsulation
Uses native shadow DOM to encapsulate styles within the component, preventing them from affecting other components.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent {
title = 'app';
}
None View Encapsulation
Disables encapsulation; styles can affect other components.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
title = 'app';
}
Component Communication
Passing data between Angular components using Input/Output decorators, EventEmitter, and services.
Parent to Child
Input Decorator - The @Input
decorator is used to pass data from a parent component to a child component. It allows the parent component to bind a property to the child component.
Example :
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Input() message: string;
}
<!--child.component.html-->
<p>{{ message }}</p>
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
message = 'Hello from parent component';
}
<!--parent.component.html-->
<app-child [message]="message"></app-child>
Child to Parent
Output Decorator - The @Output
decorator is used to pass data from a child component to a parent component. It allows the child component to emit events that the parent component can listen to.
Example :
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Output() messageEvent = new EventEmitter<string>();
sendMessage() {
this.messageEvent.emit('Hello from child component');
}
}
<!--child.component.html-->
<button (click)="sendMessage()">Send Message</button>
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
message: string;
receiveMessage($event) {
this.message = $event;
}
}
<!--parent.component.html-->
<app-child (messageEvent)="receiveMessage($event)"></app-child>
<p>{{ message }}</p>
Siblings to Siblings Communication
Using Services - Services are a way to share data and functionality between components in Angular. You can create a service that holds the data and methods that need to be shared between components.
Example 1 :
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DataService {
message: string;
setMessage(message: string) {
this.message = message;
}
getMessage() {
return this.message;
}
}
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-sibling1',
templateUrl: './sibling1.component.html',
styleUrls: ['./sibling1.component.css']
})
export class Sibling1Component {
message: string;
constructor(private dataService: DataService) {}
sendMessage() {
this.dataService.setMessage('Hello from sibling1 component');
}
}
<!--sibling1.component.html-->
<button (click)="sendMessage()">Send Message</button>
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-sibling2',
templateUrl: './sibling2.component.html',
styleUrls: ['./sibling2.component.css']
})
export class Sibling2Component {
message: string;
constructor(private dataService: DataService) {}
receiveMessage() {
this.message = this.dataService.getMessage();
}
}
<!--sibling2.component.html-->
<p>{{ message }}</p>
Example 2 :
Using RxJS Subjects - RxJS Subjects are a way to share data and events between components in Angular. You can create a Subject that emits events and subscribe to those events in the components.
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
message = new Subject<string>();
setMessage(message: string) {
this.message.next(message);
}
}
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-sibling1',
templateUrl: './sibling1.component.html',
styleUrls: ['./sibling1.component.css']
})
export class Sibling1Component {
message: string;
constructor(private dataService: DataService) {}
sendMessage() {
this.dataService.setMessage('Hello from sibling1 component');
}
}
<!--sibling1.component.html-->
<button (click)="sendMessage()">Send Message</button>
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-sibling2',
templateUrl: './sibling2.component.html',
styleUrls: ['./sibling2.component.css']
})
export class Sibling2Component {
message: string;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.message.subscribe(message => {
this.message = message;
});
}
}
<!--sibling2.component.html-->
<p>{{ message }}</p>
Example 3 :
Using ViewChild and ViewChildren - ViewChild and ViewChildren are a way to access child components in Angular. You can use ViewChild to access a single child component and ViewChildren to access multiple child components.
import { Component, ViewChild } from '@angular/core';
import { Sibling2Component } from './sibling2.component';
@Component({
selector: 'app-sibling1',
templateUrl: './sibling1.component.html',
styleUrls: ['./sibling1.component.css']
})
export class Sibling1Component {
@ViewChild(Sibling2Component) sibling2: Sibling2Component;
sendMessage() {
this.sibling2.message = 'Hello from sibling1 component';
}
}
<!--sibling1.component.html-->
<button (click)="sendMessage()">Send Message</button>
import { Component } from '@angular/core';
@Component({
selector: 'app-sibling2',
templateUrl: './sibling2.component.html',
styleUrls: ['./sibling2.component.css']
})
export class Sibling2Component {
message: string;
}
<!--sibling2.component.html-->
<p>{{ message }}</p>
Data binding
Data binding is a core feature of Angular that allows you to bind data between the component's class and the HTML template. There are two types of data binding in Angular:
There are two types of data binding in Angular:
One-way binding - This allows for passing data from the component's class to the HTML template or vice-versa.
Two-way binding - This allows for binding a property of an HTML element to a property in the component's class and vice-versa.
One way binding
One-way binding allows for passing data from the component's class to the HTML template.
There are several ways to achieve one-way binding in Angular, including:
- From Component to View
- From View to Component
1. From Component to View - This allows for passing data from the component's class to the HTML template.
There are several ways to achieve one-way binding from the component to the view in Angular, including:
- Interpolation
- Property binding
- Class binding
- Style binding
- Attribute binding
Interpolation - This allows for embedding expressions in the HTML template. It is denoted by double curly braces ({{}}).
Example :
<h1>{{ firstText }} {{ lastText }}</h1>
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
firstText = 'Interpolation';
lastText = 'Example';
}
Property binding - This allows for binding a property of an HTML element to a property in the component's class. It is denoted by square brackets ([]).
Example :
<h1 [innerText]="title"></h1>
<button [disabled]="isDisabled">I am disabled</button>
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'Angular Property Binding Example';
isDisabled = true;
}
class binding - This allows for binding a class of an HTML element to a property in the component's class. It is denoted by square brackets ([]).
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
isActive = false;
toggleActive() {
this.isActive = !this.isActive;
}
}
<div [class.active]="isActive">This div is active.</div>
<button (click)="toggleActive()">Toggle Active</button>
.active {
background-color: yellow;
}
style binding - This allows for binding a style of an HTML element to a property in the component's class. It is denoted by square brackets ([]).
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
backgroundColor = 'red';
textColor = 'white';
}
<div [style.background-color]="backgroundColor">
<h1 [style.color]="textColor">Hello, world!</h1>
</div>
attribute binding - This allows for binding an attribute of an HTML element to a property in the component's class. It is denoted by square brackets ([]).
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
imageUrl = 'https://example.com/image.jpg';
imageAlt = 'Example image';
isButtonDisabled = false;
}
<img [attr.src]="imageUrl" [attr.alt]="imageAlt">
<button [attr.disabled]="isButtonDisabled">Click me</button>
b. From View to Component - This allows for passing data from the HTML template to the component's class.
There are several ways to achieve one-way binding from the view to the component in Angular, including:
- Event binding
- ngModel
Event binding - This allows for binding an event of an HTML element to a method in the component's class. It is denoted by parentheses (()).
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
onClick() {
console.log('Button was clicked');
}
}
<h1>Event Binding Example</h1>
<button (click)="onClick()">Click me</button>
ngModel - The ngModel
directive is used to create two-way data binding between an input element and a property in the component's class. It is commonly used to bind form controls to properties in the component.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name: string = '';
}
<input [(ngModel)]="name" placeholder="Enter your name">
<p>Your name is: {{name}}</p>
Remeber💡 :
The (click) calls the specified function when a user clicks on the given element (in your example, when a user clicks on a row).
The (change) event binds to HTML's onChange event. This event is fired for <input>
, <select>
, and <textarea>
elements when a change to the element's value is committed by the user.
The (change) event can also be specifically implemented by other Angular components. It is generally implemented on components where the contents of the component are changed by the user.
Two ways binding
Two-way binding allows for binding a property of an HTML element to a property in the component's class and vice-versa. It is denoted by [(ngModel)]
.
There are several ways to achieve two-way binding in Angular, including:
- ngModel
- ngModelChange
- change event
ngModel - The ngModel
directive is used to create two-way data binding between an input element and a property in the component's class. It is commonly used to bind form controls to properties in the component.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name: string = '';
}
<input [(ngModel)]="name" placeholder="Enter your name">
<p>Your name is: {{name}}</p>
ngModelChange - The ngModelChange
event is emitted when the value of an input element bound to ngModel
changes. It can be used to perform additional logic when the value changes.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name: string = '';
onNameChange(value: string) {
console.log('Name changed to:', value);
}
}
<input [(ngModel)]="name" (ngModelChange)="onNameChange($event)" placeholder="Enter your name">
<p>Your name is: {{name}}</p>
change event - The change
event is emitted when the value of an input element changes. It can be used to perform additional logic when the value changes.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name: string = '';
onNameChange(value: string) {
console.log('Name changed to:', value);
}
}
<input [(ngModel)]="name" (change)="onNameChange($event.target.value)" placeholder="Enter your name">
<p>Your name is: {{name}}</p>
Directives
Directives add behaviour to an existing DOM element or an existing component instance.
Types of Directives
There are three types of directives in Angular:
Structural Directives - Structural directives are used to add or remove elements from the DOM based on a condition. They are denoted by an asterisk (*) before the directive name.
Attribute Directives - Attribute directives are used to change the appearance or behavior of an element. They are denoted by square brackets [] before the directive name.
Custom Directives - Custom directives are user-defined directives that add custom behavior to an element. They can be used to encapsulate complex behavior and reuse it across multiple components.
Structural Directives
There are several built-in structural directives in Angular, including:
- NgIf
- NgFor
- NgSwitch
ngIf - The ngIf
directive is used to conditionally display elements based on the value of a given expression. It is commonly used to show or hide elements in the UI based on certain conditions.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
showElement = true;
}
<h1>ngIf Example</h1>
<div *ngIf="showElement">
This element will only be displayed if showElement is true.
</div>
ngFor - The ngFor
directive is used to iterate over a list of items and create a template for each item. It is commonly used to display a list of items in the UI.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
items = ['Item 1', 'Item 2', 'Item 3'];
}
<h1>ngFor Example</h1>
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
ngSwitch - The ngSwitch
directive is used to conditionally display elements based on the value of a given expression. It is similar to a switch statement in JavaScript.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
value = 1;
}
<h1>ngSwitch Example</h1>
<div [ngSwitch]="value">
<div *ngSwitchCase="1">Case 1</div>
<div *ngSwitchCase="2">Case 2</div>
<div *ngSwitchCase="3">Case 3</div>
<div *ngSwitchDefault>Default case</div>
</div>
Attribute Directives
There are several built-in attribute directives in Angular, including:
- NgClass
- NgStyle
- NgModel
ngClass - The ngClass
directive is used to conditionally apply CSS classes to an element based on the value of a given expression. It is commonly used to apply styles to elements based on certain conditions.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
isHighlighted = true;
}
<h1>ngClass Example</h1>
<div [ngClass]="{ highlighted: isHighlighted }">
This element will have the 'highlighted' class if isHighlighted is true.
</div>
.highlighted {
background-color: yellow;
}
ngStyle - The ngStyle
directive is used to conditionally apply inline styles to an element based on the value of a given expression. It is commonly used to apply dynamic styles to elements based on certain conditions.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
color = 'red';
}
<h1>ngStyle Example</h1>
<div [ngStyle]="{ color: color }">
This element will have the color style set to the value of the color property.
</div>
ngModel - The ngModel
directive is used to create two-way data binding between an input element and a property in the component's class. It is commonly used to bind form controls to properties in the component.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name: string;
}
<h1>ngModel Example</h1>
<form>
<label for="name">Name:</label>
<input type="text" id="name" [(ngModel)]="name" name="name" />
</form>
Custom Directives
Custom directives are user-defined directives that add custom behavior to an element. They can be used to encapsulate complex behavior and reuse it across multiple components.
Example :
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appCustomDirective]',
})
export class CustomDirectiveDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CustomDirectiveDirective } from './custom-directive.directive';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent, CustomDirectiveDirective],
bootstrap: [AppComponent],
})
export class AppModule {}
<h1>Custom Directive Element</h1>
<div appCustomDirective>
This element will have a yellow background when the mouse is over it.
</div>
Other directives
There are several other built-in directives in Angular, including:
- ngContainer
- ngTemplate
- ngContent
- ngTemplateOutlet
ngContainer - The ngContainer
directive is a simple container that doesn't generate any markup in the DOM. It's mainly used as a placeholder to group and structure content within Angular templates.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
condition = true;
}
<h1>ngContainer Example</h1>
<div *ngIf="condition">
<ng-container>
<p>Content to be conditionally rendered</p>
<p>More content...</p>
</ng-container>
</div>
ngTemplate - The ngTemplate
directive is used to define a reusable template block that can be used later within the same component or shared across components using the ngTemplateOutlet directive.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
selectedTemplate: any;
}
<h1>ngTemplate Example</h1>
<ng-template #myTemplate>
<p>This is a template</p>
<p>It can be reused in multiple places</p>
</ng-template>
<div>
<ng-container *ngTemplateOutlet="selectedTemplate"></ng-container>
</div>
<button (click)="selectedTemplate = myTemplate">Load Template</button>
ngContent - The ngContent
directive is used for content projection or transclusion. It allows you to create reusable components with customizable content.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
})
export class ChildComponent {}
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent {}
<!-- Parent Component -->
<app-child>
<p>Content projected into the child component</p>
</app-child>
<!-- Child Component Template -->
<div>
<ng-content></ng-content>
</div>
ngTemplateOutlet - The ngTemplateOutlet
directive is used to render a template defined using ngTemplate. It allows you to dynamically render a template within a component's template.
Example :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
selectedTemplate: any;
}
<h1>ngTemplateOutlet Example</h1>
<ng-container *ngTemplateOutlet="selectedTemplate"></ng-container>
<ng-template #template1>
Template 1 content
</ng-template>
<ng-template #template2>
Template 2 content
</ng-template>
<button (click)="selectedTemplate = template1">Load Template 1</button>
<button (click)="selectedTemplate = template2">Load Template 2</button>
Pipes
A pipe takes in data as input and transforms it to a desired output.
Syntax:
{{ data | pipe }}
Expression | pipeOperator[:pipeArguments]
# Expression: is the expression, which you want to transform
# | : is the Pipe Character
# pipeOperator : name of the Pipe
# pipeArguments: arguments to the Pipe
Built-in Pipes
There are several built-in pipes in Angular, including:
- Date Pipe
- Uppercase Pipe
- Lowercase Pipe
- Currency Pipe
- Percent Pipe
- Slice Pipe
- Decimal/number Pipe
- JSON Pipe
- Async Pipe
Date Pipe
The date
pipe is used to format a date value according to the locale rules specified in the application.
import { DatePipe } from '@angular/common';
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
date = new Date();
constructor(private datePipe: DatePipe) {}
formatDate() {
return this.datePipe.transform(this.date, 'shortDate');
}
}
<h1>Date Pipe Example</h1>
<p>{{ date | date: 'shortDate' }}</p>
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { DatePipe } from '@angular/common';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [DatePipe],
})
export class AppModule {}
Uppercase Pipe
The uppercase
pipe is used to transform a string to uppercase.
<h1>Upper Case Pipe Example</h1>
<p>{{ name | uppercase }}</p>
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Manthan Ank';
}
Lowercase Pipe
The lowercase
pipe is used to transform a string to lowercase.
<p>{{ name | lowercase }}</p>
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Manthan Ank';
}
Currency Pipe
The currency
pipe is used to format a number as currency using the locale rules specified in the application.
<h1>Currency Pipe Example</h1>
<p>{{ price | currency }}</p>
import { CurrencyPipe } from '@angular/common';
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
price = 100;
constructor(private currencyPipe: CurrencyPipe) { }
formatCurrency() {
return this.currencyPipe.transform(this.price, 'USD', true);
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CurrencyPipe } from '@angular/common';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [CurrencyPipe],
})
export class AppModule {}
Percent Pipe
The percent
pipe is used to format a number as a percentage.
<h1>Percent Pipe Example</h1>
<p>{{ percentage | percent }}</p>
import { PercentPipe } from '@angular/common';
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
percentage = 0.5;
constructor(private percentPipe: PercentPipe) {}
formatPercentage() {
return this.percentPipe.transform(this.percentage, '2');
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { PercentPipe } from '@angular/common';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PercentPipe],
})
export class AppModule {}
Slice Pipe
The slice
pipe is used to create a new array or string containing a subset of the elements of the input array or string.
<p>{{ ['apple', 'banana', 'orange', 'mango'] | slice:1:3 }}</p>
Decimal/number Pipe
The number
pipe is used to format a number as text. It can be used to format a number as a percentage, currency, or decimal number.
<p>{{ 123456.78 | number:'3.2-3' }}</p>
JSON Pipe
The json
pipe is used to transform a JavaScript object into a JSON string.
<p>{{data | json}}</p>
Async Pipe
The async
pipe is used to subscribe to an Observable or Promise and return the latest value it has emitted.
<p>{{data$ | async}}</p>
// DataService.service.ts
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable()
export class DataService {
private data$: Observable<string>;
constructor() {
// Simulating an asynchronous data source
this.data$ = of('Hello, async pipe!').pipe(
// Simulating delay
delay(2000)
);
}
getData(): Observable<string> {
return this.data$;
}
}
// ExampleComponent.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { DataService } from './data.service';
@Component({
selector: 'app-example',
template: '<div>{{ data$ | async }}</div>',
})
export class ExampleComponent {
data$: Observable<string>;
constructor(private dataService: DataService) {
this.data$ = this.dataService.getData();
}
}
Impure Pipes
By default, Angular pipes are pure, meaning they are stateless and do not change unless the input value changes. However, you can create impure pipes by setting the pure property to false in the @Pipe decorator.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'impurePipe',
pure: false,
})
export class ImpurePipe implements PipeTransform {
transform(value: any): any {
return value;
}
}
Decorators
Decorators are design patterns used to isolate the modification or decoration of a class without modifying the source code.
There are several built-in decorators in Angular, including:
- @Component
- @Directive
- @Injectable
- @Pipe
- @NgModule
- @Input
- @Output
- @HostListener
- @ContentChild
- @ContentChildren
- @ViewChild
- @ViewChildren
Component
The @Component
decorator is used to define a new component in Angular.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'My App';
}
<h1>{{ title }}</h1>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
Directive
The @Directive
decorator is used to define a new directive in Angular.
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appCustomDirective]',
})
export class CustomDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
<div appCustomDirective>
This element will have a yellow background when the mouse is over it.
</div>
import { NgModule } from '@angular/core';
import { CustomDirective } from './custom.directive';
@NgModule({
declarations: [CustomDirective],
})
export class AppModule {}
Injectable
The @Injectable
decorator is used to define a new service in Angular.
import { Injectable } from '@angular/core';
@Injectable
export class DataService {
getData() {
return 'Hello, world!';
}
}
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
data: string;
constructor(private dataService: DataService) {
this.data = this.dataService.getData();
}
}
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
providers: [DataService],
})
export class AppModule {}
Pipe
The @Pipe
decorator is used to define a new pipe in Angular.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe',
})
export class CustomPipe implements PipeTransform {
transform(value: any, args?: any): any {
return value;
}
}
<h1>{{ data | customPipe }}</h1>
import { NgModule } from '@angular/core';
import { CustomPipe } from './custom.pipe';
@NgModule({
declarations: [CustomPipe],
})
export class AppModule {}
NgModule
The @NgModule
decorator is used to define a new module in Angular.
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: [],
providers: [],
bootstrap: [],
})
export class AppModule {}
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
Input
The @Input
decorator is used to pass data from a parent component to a child component.
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() message: string;
constructor() { }
ngOnInit() {}
}
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent implements OnInit {
parentMessage = 'Hello from the parent component!';
constructor() {}
ngOnInit() {}
}
<p>{{ message }}</p>
<app-child [message]="parentMessage"></app-child>
<h1>@Input Example</h1>
<app-parent></app-parent>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';
import { ChildComponent } from './child/child.component';
import { ParentComponent } from './parent/parent.component';
@NgModule({
imports: [BrowserModule, FormsModule, RouterModule],
declarations: [AppComponent, ChildComponent, ParentComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
Output
The @Output
decorator is used to pass data from a child component to a parent component.
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
})
export class ChildComponent implements OnInit {
@Output() messageEvent = new EventEmitter<string>();
constructor() {}
ngOnInit() {}
sendMessage() {
this.messageEvent.emit('Hello from the child component!');
}
}
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent implements OnInit {
constructor() {}
ngOnInit() {}
handleMessage(message: string) {
console.log(message);
}
}
<button (click)="sendMessage()">Send message</button>
<app-child (messageEvent)="handleMessage($event)"></app-child>
<h1>@Output Decorator Example</h1>
<app-parent></app-parent>
HostListener
The @HostListener
decorator is used to listen for events on the host element of a directive or component.
<h1>@HostListener Decorator Example</h1>
<p>Click the host element to trigger the 'click' event.</p>
import { Component, HostListener } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],