Angular is a TypeScript-based open-source web application framework developed by Google for building dynamic single-page applications (SPAs).
// A simple Angular component structure // This demonstrates a basic component in Angular <!-- app.component.ts --> import { Component } from '@angular/core'; // Import Component decorator @Component({ selector: 'app-root', // The HTML selector to use this component templateUrl: './app.component.html', // HTML file for view styleUrls: ['./app.component.css'] // CSS file for styles }) export class AppComponent { title = 'My Angular App'; // Property bound to HTML }
AngularJS (1.x) was released in 2010. In 2016, Angular (2+) was released as a complete rewrite using TypeScript, offering better performance, modularity, and modern architecture.
// AngularJS vs Angular (TypeScript) // AngularJS - JavaScript based (Old Version) var app = angular.module('myApp', []); // Define module app.controller('myCtrl', function($scope) { $scope.name = 'AngularJS'; // Scope variable }); // Angular (2+) - TypeScript based (Modern Version) import { Component } from '@angular/core'; // Importing decorator @Component({ selector: 'my-app', template: '<h1>Welcome to Angular 2+</h1>' // Inline template }) export class AppComponent {}
AngularJS uses JavaScript and is based on the MVC architecture, whereas Angular uses TypeScript and is based on a component-based architecture with improved performance.
// AngularJS example <div ng-app="myApp" ng-controller="myCtrl"> <p>{{ greeting }}</p> </div> // Angular example <!-- app.component.html --> <p>{{ greeting }}</p>
Angular is a complete framework, React is a library for UI rendering, and Vue is a progressive framework combining ideas from both.
// Angular: Full Framework (routing, HTTP, etc.) <router-outlet></router-outlet> // Placeholder for routed views // React: Library for building UI function App() { return <h1>Hello React</h1>; } // Vue: Lightweight and flexible <template> <h1>Hello Vue</h1> </template>
You should have knowledge of HTML, CSS, JavaScript, and TypeScript. Tools needed include Node.js, npm, and Angular CLI.
// Check if Node.js is installed node -v // Displays Node.js version // Check npm version npm -v // Displays npm version // Install Angular CLI globally npm install -g @angular/cli // Installs CLI
Angular CLI is a command-line interface for creating and managing Angular projects easily.
// Install Angular CLI npm install -g @angular/cli // Global installation // Verify Angular CLI ng version // Shows installed Angular version
You can create a new Angular app using the CLI command below.
// Create a new Angular app ng new my-first-app // Starts a project setup // Navigate into the project folder cd my-first-app // Move to project directory // Run the development server ng serve // Starts the app on localhost:4200
An Angular project contains modules, components, services, and configuration files.
// Common folders in Angular project src/ app/ app.component.ts // Component logic app.module.ts // App's root module app.component.html // HTML template assets/ // Static files like images environments/ // Dev & prod config angular.json // Project config package.json // Dependencies tsconfig.json // TypeScript settings
TypeScript is a strongly typed superset of JavaScript that compiles to plain JavaScript. It provides features like static typing, interfaces, and class-based OOP which make it ideal for Angular development.
// A simple TypeScript variable example let message: string = 'Hello, TypeScript!'; // Declare a string variable console.log(message); // Print the message
TypeScript supports primitive types and allows defining custom types using interfaces.
// Basic types let isDone: boolean = true; // Boolean type let age: number = 25; // Number type let name: string = 'John'; // String type // Interface for a user object interface User { id: number; // Number property name: string; // String property } let user: User = { id: 1, name: 'Alice' }; // Object implementing interface
TypeScript supports object-oriented programming through classes, constructors, and access modifiers.
// Define a class class Person { private name: string; // Private property constructor(name: string) { this.name = name; // Initialize name } greet(): void { console.log('Hello, ' + this.name); // Method to greet } } let person = new Person('Alice'); // Create an object person.greet(); // Call method
Modules in TypeScript help organize code. Namespaces can also be used to group related functionalities.
// user.ts - exporting a class export class User { constructor(public name: string) {} // Public property } // main.ts - importing and using the module import { User } from './user'; // Import module let u = new User('Bob'); // Create object console.log(u.name); // Print name
TypeScript supports regular functions and ES6 arrow functions for cleaner syntax.
// Regular function function add(a: number, b: number): number { return a + b; // Return sum } // Arrow function const multiply = (a: number, b: number): number => { return a * b; // Return product } console.log(add(2, 3)); // Outputs: 5 console.log(multiply(4, 5)); // Outputs: 20
Generics allow you to create reusable components. Enums let you define named constants.
// Generic function function identity<T>(arg: T): T { return arg; // Return argument } console.log(identity<string>('TypeScript')); // Outputs: TypeScript // Enum example enum Color { Red, Green, Blue } let c: Color = Color.Green; // Assign enum console.log(c); // Outputs: 1
Compiler options are configured in tsconfig.json
to control code generation and checking.
{ "compilerOptions": { "target": "es6", // JavaScript version "module": "commonjs", // Module system "strict": true, // Enable strict type checks "esModuleInterop": true // Compatibility setting } }
Angular is built using TypeScript. All components, services, and modules in Angular are written in TypeScript.
// app.component.ts - Angular component in TypeScript import { Component } from '@angular/core'; // Import component decorator @Component({ selector: 'app-root', // HTML tag for the component template: '<h1>{{ title }}</h1>', // Inline template }) export class AppComponent { title: string = 'Angular + TypeScript'; // Property with type annotation }
In Angular, a component is a building block of the UI. It includes an HTML template, a CSS style, and TypeScript logic.
// A simple component in Angular import { Component } from '@angular/core'; // Import Component decorator @Component({ selector: 'app-hello', // Component selector tag template: '<p>Hello, Angular!</p>', // Inline HTML template styles: ['p { color: blue; }'] // Inline CSS styles }) export class HelloComponent { // No logic for this basic example }
The @Component
decorator defines metadata like selector, template, and style for the component.
// Using @Component decorator @Component({ selector: 'app-welcome', // Custom HTML tag templateUrl: './welcome.component.html', // External HTML file styleUrls: ['./welcome.component.css'] // External CSS file }) export class WelcomeComponent { title: string = 'Welcome to Angular'; // Component property }
Templates define the HTML, while styles add CSS to format the component’s view.
// welcome.component.html <h2>{{ title }}</h2> // Binding the title property <p>This is the welcome component.</p> // welcome.component.css h2 { color: green; // Style the heading }
Angular components have lifecycle hooks like ngOnInit
and ngOnDestroy
.
import { Component, OnInit, OnDestroy } from '@angular/core'; // Import lifecycle interfaces @Component({ selector: 'app-logger', template: '<p>Check the console for logs.</p>' }) export class LoggerComponent implements OnInit, OnDestroy { ngOnInit() { console.log('Component Initialized'); // Called once component loads } ngOnDestroy() { console.log('Component Destroyed'); // Called before component is removed } }
Nested components are child components used within a parent component.
// parent.component.html <app-child></app-child> // Nesting the child component // child.component.ts @Component({ selector: 'app-child', template: '<p>This is the child component.</p>' }) export class ChildComponent {}
@Input()
allows data to be passed from a parent component to a child component.
// child.component.ts import { Component, Input } from '@angular/core'; // Import Input decorator @Component({ selector: 'app-child', template: '<p>Received: {{ data }}</p>' }) export class ChildComponent { @Input() data!: string; // Input property to receive data } // parent.component.html <app-child [data]="parentData"></app-child> // parent.component.ts export class ParentComponent { parentData: string = 'Hello from Parent'; // Data to send to child }
@Output()
with EventEmitter allows child components to send data to parent components.
// child.component.ts import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: '<button (click)="sendData()">Send to Parent</button>' }) export class ChildComponent { @Output() notify = new EventEmitter<string>(); // Declare EventEmitter sendData() { this.notify.emit('Message from child'); // Emit event to parent } } // parent.component.html <app-child (notify)="onNotify($event)"></app-child> // parent.component.ts export class ParentComponent { onNotify(message: string) { console.log(message); // Handle emitted event } }
Follow these tips:
// Good practice: Separate logic, template, and styles @Component({ selector: 'app-clean', templateUrl: './clean.component.html', // External HTML styleUrls: ['./clean.component.css'] // External CSS }) export class CleanComponent { data: string = 'Organized component'; // Component data }
Angular templates use HTML enhanced with Angular directives and binding syntax to connect data between class and template.
<!-- Display a message using interpolation --> <h1>{{ message }}</h1>
Interpolation {{ }}
binds data from the component class to the view.
// In app.component.ts export class AppComponent { message: string = 'Welcome to Angular'; // Declare message }
<!-- In app.component.html --> <p>{{ message }}</p> <!-- Binds message to paragraph -->
Property binding [property]
sets the property of an HTML element or directive.
// In app.component.ts export class AppComponent { imageUrl: string = 'https://example.com/image.jpg'; // Image URL }
<!-- In app.component.html --> <img [src]="imageUrl" alt="Example Image"> <!-- Binds src attribute to imageUrl -->
Event binding (event)
lets you respond to user actions like clicks.
// In app.component.ts export class AppComponent { showMessage(): void { alert('Button clicked!'); // Show alert on click } }
<!-- In app.component.html --> <button (click)="showMessage()">Click Me</button> <!-- Calls showMessage on click -->
Two-way binding uses [(ngModel)]
to bind data both ways between the component and template.
// In app.component.ts export class AppComponent { name: string = ''; // Variable to bind input }
<!-- In app.component.html --> <input [(ngModel)]="name" placeholder="Enter your name"> <!-- Two-way bind to name --> <p>Hello, {{ name }}!</p> <!-- Display name in real-time -->
Reference variables #
give access to elements in the template.
<input #userInput type="text"> <!-- Create reference variable --> <button (click)="alert(userInput.value)">Show Input</button> <!-- Access input value -->
The ngModel
directive enables two-way data binding with form elements.
// In app.component.ts export class AppComponent { email: string = ''; // Bind input to email }
<!-- In app.component.html --> <input type="email" [(ngModel)]="email" placeholder="Enter email"> <p>Entered Email: {{ email }}</p>
Safe navigation ?.
prevents null reference errors. Pipes transform data in the template.
// In app.component.ts export class AppComponent { user: any = { name: 'Alice', birthday: new Date(1990, 1, 1) // Example date }; }
<!-- In app.component.html --> <p>Name: {{ user?.name }}</p> <!-- Safe access to name --> <p>Birthday: {{ user?.birthday | date:'longDate' }}</p> <!-- Format using date pipe -->
Directives are special markers on elements that tell Angular to do something with the DOM. They come in three types: component, attribute, and structural.
// Directive types explained in comment only // Component - A directive with a template // Structural Directive - Changes the DOM layout by adding/removing elements // Attribute Directive - Changes the appearance or behavior of an element
Structural directives modify the layout of the DOM. Common ones include *ngIf
, *ngFor
, and *ngSwitch
.
<div *ngIf="isVisible"> // Only show if isVisible is true <p>This is conditionally visible.</p> </div>
<ul> <li *ngFor="let item of items"> // Loop through 'items' array {{ item }} // Display each item </li> </ul>
<div [ngSwitch]="color"> // Switch based on the 'color' variable <div *ngSwitchCase="'red'">Red Color</div> // Case when color is 'red' <div *ngSwitchCase="'blue'">Blue Color</div> // Case when color is 'blue' <div *ngSwitchDefault>No color matched</div> // Default fallback </div>
Attribute directives change the appearance or behavior of an element. Common ones include ngClass
and ngStyle
.
<div [ngClass]="{ 'active': isActive }"> // Apply 'active' class if isActive is true This box uses ngClass </div>
<div [ngStyle]="{ 'color': isRed ? 'red' : 'black' }"> // Change color based on isRed Text styled with ngStyle </div>
You can create your own attribute directives to add behavior to elements.
// highlight.directive.ts import { Directive, ElementRef } from '@angular/core'; // Import required classes @Directive({ selector: '[appHighlight]' // Use with an attribute: appHighlight }) export class HighlightDirective { constructor(el: ElementRef) { el.nativeElement.style.backgroundColor = 'yellow'; // Change background color } } // usage in component template <p appHighlight>This is highlighted</p> // Apply custom directive
Structural directives can be custom-built using ViewContainerRef
and TemplateRef
.
// unless.directive.ts import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[appUnless]' // Use like *appUnless }) export class UnlessDirective { constructor( private templateRef: TemplateRef<any>, // Template to render private viewContainer: ViewContainerRef // Container for rendering view ) {} @Input() set appUnless(condition: boolean) { if (!condition) { this.viewContainer.createEmbeddedView(this.templateRef); // Show if condition is false } else { this.viewContainer.clear(); // Hide if condition is true } } } // usage <div *appUnless="isLoggedIn">Please log in</div>
These decorators allow interaction with the host element: binding properties or listening to events.
// hover-highlight.directive.ts import { Directive, HostListener, HostBinding } from '@angular/core'; @Directive({ selector: '[appHoverHighlight]' // Custom directive for hover }) export class HoverHighlightDirective { @HostBinding('style.backgroundColor') bgColor = 'white'; // Bind background color @HostListener('mouseenter') onMouseEnter() { this.bgColor = 'lightblue'; // Change color on hover } @HostListener('mouseleave') onMouseLeave() { this.bgColor = 'white'; // Reset color on mouse leave } } // usage <p appHoverHighlight>Hover over me!</p>
Services are classes used to share data and logic across components, keeping components lean and reusable.
// Example of a simple Angular service import { Injectable } from '@angular/core'; // Import Injectable decorator @Injectable({ providedIn: 'root' // Service is singleton and available app-wide }) export class DataService { private data: string = 'Service Data'; // Private data property getData(): string { return this.data; // Method to return data } }
Generate a service with Angular CLI or manually create a class with @Injectable()
.
// Manual service creation import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class LoggerService { log(message: string) { console.log('LoggerService:', message); // Log messages to console } }
Inject services into components to use their logic and data.
// Injecting a service into a component import { Component } from '@angular/core'; import { DataService } from './data.service'; // Import service @Component({ selector: 'app-sample', template: '<p>{{ data }}</p>' }) export class SampleComponent { data: string; constructor(private dataService: DataService) { this.data = this.dataService.getData(); // Use service method } }
By default, services provided in root are singleton, meaning one instance is shared throughout the app.
// Singleton service example is same as DataService above // Only one instance exists and shared across components
This decorator marks a class as available for DI and defines the provider scope.
@Injectable({ providedIn: 'root' // Service available application-wide }) export class AuthService { isLoggedIn: boolean = false; login() { this.isLoggedIn = true; // Set logged in status } logout() { this.isLoggedIn = false; // Set logged out status } }
Angular has hierarchical injectors allowing different instances of services in different modules or components.
// Providing a service in a component to create a separate instance @Component({ selector: 'app-child', template: '<p>Child Component</p>', providers: [LoggerService] // This creates a new instance only for this component }) export class ChildComponent { constructor(private logger: LoggerService) { this.logger.log('Child component logger'); // Logs using this instance } }
Services live as long as their injector does — root services live through app lifecycle, component-provided services live with the component.
// Root-level services live app-wide (singleton) // Component-level services created/destroyed with component lifecycle
Keep services focused, reusable, and stateless where possible. Avoid logic in components that can be moved to services.
// Example best practice: separate concerns @Injectable({ providedIn: 'root' }) export class ApiService { fetchData() { // Logic to fetch data from API } }
Routing enables navigation between different views or components in Angular apps.
// app-routing.module.ts import { NgModule } from '@angular/core'; // Import NgModule decorator import { RouterModule, Routes } from '@angular/router'; // Import RouterModule and Routes const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, // Redirect root path to /home { path: 'home', component: HomeComponent }, // Route for HomeComponent { path: 'about', component: AboutComponent } // Route for AboutComponent ]; @NgModule({ imports: [RouterModule.forRoot(routes)], // Initialize router with routes exports: [RouterModule] // Export RouterModule for app module }) export class AppRoutingModule { }
RouterModule
registers router configuration; Routes
define paths and their components.
const routes: Routes = [ { path: 'dashboard', component: DashboardComponent }, // Dashboard route { path: 'profile', component: ProfileComponent } // Profile route ];
RouterLink
is used in templates to navigate via clickable links.
<nav> <a routerLink="/home">Home</a> <!-- Link to Home route --> <a routerLink="/about">About</a> <!-- Link to About route --> </nav>
Routes can have parameters to pass dynamic values like IDs.
// Define route with parameter { path: 'user/:id', component: UserComponent } // Access parameter inside UserComponent import { ActivatedRoute } from '@angular/router'; export class UserComponent { constructor(private route: ActivatedRoute) { this.route.params.subscribe(params => { console.log(params['id']); // Log user id from URL }); } }
Child routes allow nested navigation inside a parent route.
const routes: Routes = [ { path: 'admin', component: AdminComponent, children: [ { path: 'users', component: UsersComponent }, // Child route for users { path: 'settings', component: SettingsComponent } // Child route for settings ]} ];
Redirects send users from one URL to another; wildcards handle unknown URLs.
{ path: '', redirectTo: '/home', pathMatch: 'full' }, // Redirect empty path { path: '**', component: PageNotFoundComponent } // Wildcard for 404 page
Modules can be loaded on demand to optimize app performance.
const routes: Routes = [ { path: 'shop', loadChildren: () => import('./shop/shop.module').then(m => m.ShopModule) } ];
Guards protect routes, allowing or blocking navigation based on logic (e.g., authentication).
// auth.guard.ts import { Injectable } from '@angular/core'; import { CanActivate, Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate(): boolean { const loggedIn = false; // Simulated auth check if (!loggedIn) { this.router.navigate(['/login']); // Redirect if not logged in return false; } return true; // Allow access if logged in } } // Applying guard in routes const routes: Routes = [ { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] } ];
Template-driven forms are simple forms where most logic is in the template using Angular directives.
// app.module.ts (import FormsModule) import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ FormsModule // Import FormsModule for template-driven forms ], }) export class AppModule {} // simple-form.component.html <form #formRef="ngForm" (ngSubmit)="onSubmit(formRef)"> <input name="username" ngModel required /> <!-- Two-way binding with ngModel --> <button type="submit">Submit</button> </form> // simple-form.component.ts export class SimpleFormComponent { onSubmit(form: any) { console.log(form.value); // Log form values on submit } }
Reactive forms use explicit form model in the component class for more control.
// app.module.ts (import ReactiveFormsModule) import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ ReactiveFormsModule // Import ReactiveFormsModule for reactive forms ], }) export class AppModule {} // reactive-form.component.ts import { FormGroup, FormControl } from '@angular/forms'; export class ReactiveFormComponent { form = new FormGroup({ username: new FormControl(''), // Initialize FormControl for username }); onSubmit() { console.log(this.form.value); // Log form values on submit } } // reactive-form.component.html <form [formGroup]="form" (ngSubmit)="onSubmit()"> <input formControlName="username" /> <!-- Bind input to formControlName --> <button type="submit">Submit</button> </form>
FormGroup is a group of FormControls, representing the entire form or part of it.
import { FormGroup, FormControl } from '@angular/forms'; export class ProfileFormComponent { profileForm = new FormGroup({ firstName: new FormControl(''), // Control for first name lastName: new FormControl(''), // Control for last name }); onSubmit() { console.log(this.profileForm.value); // Log all form values } }
Validators ensure form input meets criteria; custom validators allow custom logic.
import { Validators, AbstractControl, ValidationErrors } from '@angular/forms'; // Custom validator function example function forbiddenNameValidator(control: AbstractControl): ValidationErrors | null { const forbidden = /admin/.test(control.value); // Check if value contains 'admin' return forbidden ? { forbiddenName: { value: control.value } } : null; } export class SignupFormComponent { signupForm = new FormGroup({ username: new FormControl('', [Validators.required, forbiddenNameValidator]) // Apply validators }); onSubmit() { if (this.signupForm.valid) { console.log('Form Submitted', this.signupForm.value); } } }
FormBuilder service helps create form controls and groups more concisely.
import { FormBuilder, Validators } from '@angular/forms'; export class LoginFormComponent { constructor(private fb: FormBuilder) {} loginForm = this.fb.group({ email: ['', [Validators.required, Validators.email]], // Email control with validators password: ['', Validators.required] // Password control with required validator }); onSubmit() { console.log(this.loginForm.value); // Log form values on submit } }
Forms can listen to changes using valueChanges
observable.
this.loginForm.get('email')?.valueChanges.subscribe(value => { console.log('Email changed:', value); // React to email input changes });
Dynamic forms allow adding/removing controls programmatically.
import { FormArray, FormBuilder } from '@angular/forms'; export class DynamicFormComponent { constructor(private fb: FormBuilder) {} form = this.fb.group({ aliases: this.fb.array([ this.fb.control('') ]) // FormArray to hold multiple aliases }); get aliases() { return this.form.get('aliases') as FormArray; } addAlias() { this.aliases.push(this.fb.control('')); // Add a new control dynamically } }
Show error messages when controls are invalid and touched.
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> <input formControlName="email" /> <div *ngIf="loginForm.get('email')?.invalid && loginForm.get('email')?.touched"> <small class="text-danger">Email is invalid</small> </div> <button type="submit">Submit</button> </form>
Pipes transform displayed data in templates, formatting values easily.
<!-- app.component.ts --> export class AppComponent { title: string = 'angular pipes example'; // Sample title string }
<!-- app.component.html --> <p>Original: {{ title }}</p> <!-- Display raw string --> <p>Uppercase: {{ title | uppercase }}</p> <!-- Transform to uppercase -->
Angular provides built-in pipes for common transformations like date and currency.
<!-- app.component.ts --> export class AppComponent { today: Date = new Date(); // Current date price: number = 1234.56; // Sample price }
<!-- app.component.html --> <p>Date: {{ today | date:'fullDate' }}</p> <!-- Format date --> <p>Currency: {{ price | currency:'USD' }}</p> <!-- Format currency -->
Custom pipes let you create your own transformations.
<!-- greet.pipe.ts --> import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'greet' // Pipe name used in template }) export class GreetPipe implements PipeTransform { transform(value: string): string { return 'Hello, ' + value + '!'; // Prepend greeting } }
<!-- app.component.html --> <p>{{ 'John' | greet }}</p> <!-- Outputs: Hello, John! -->
Pure pipes execute only when input changes; impure pipes run on every change detection cycle.
@Pipe({ name: 'impureExample', pure: false // Mark pipe as impure })
Pipes can accept parameters for dynamic formatting.
<!-- app.component.html --> <p>Currency with symbol: {{ price | currency:'EUR':'symbol' }}</p> <p>Date with format: {{ today | date:'shortDate' }}</p>
You can chain multiple pipes for combined transformations.
<p>{{ title | lowercase | slice:0:7 | uppercase }}</p> <!-- Converts to lowercase, slices substring, then uppercase -->
The async pipe subscribes to observables or promises and returns their latest value.
<!-- app.component.ts --> import { Component } from '@angular/core'; import { Observable, of } from 'rxjs'; export class AppComponent { data$: Observable<string> = of('Async Pipe Example'); // Observable emitting string }
<!-- app.component.html --> <p>{{ data$ | async }}</p> <!-- Displays latest observable value -->
The HttpClientModule provides a simplified API for HTTP communications. It must be imported in your Angular app module.
// app.module.ts import { HttpClientModule } from '@angular/common/http'; // Import HttpClientModule @NgModule({ imports: [ HttpClientModule // Add HttpClientModule to imports ], }) export class AppModule { }
// my-service.service.ts import { HttpClient } from '@angular/common/http'; // Import HttpClient import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' // Provide service at root level }) export class MyService { constructor(private http: HttpClient) {} // Inject HttpClient getData() { return this.http.get<any>('https://api.example.com/data'); // Send GET request } }
// my-service.service.ts (continued) postData(data: any) { return this.http.post('https://api.example.com/data', data); // Send POST request with data } updateData(id: number, data: any) { return this.http.put(`https://api.example.com/data/${id}`, data); // Send PUT request to update data } deleteData(id: number) { return this.http.delete(`https://api.example.com/data/${id}`); // Send DELETE request by id }
import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; getData() { return this.http.get('https://api.example.com/data').pipe( catchError(error => { console.error('Error occurred:', error); // Log error return throwError(() => new Error('Something bad happened; please try again later.')); // Return user-friendly error }) ); }
HttpClient methods return Observables, allowing reactive programming with streams.
this.myService.getData().subscribe({ next: data => { console.log('Data received:', data); // Handle successful data }, error: error => { console.error('There was an error:', error); // Handle error } });
Interceptors allow you to intercept and modify HTTP requests or responses globally.
// auth.interceptor.ts import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const clonedReq = req.clone({ headers: req.headers.set('Authorization', 'Bearer my-token') // Add auth header }); return next.handle(clonedReq); // Pass the modified request } }
import { HttpParams, HttpHeaders } from '@angular/common/http'; const headers = new HttpHeaders().set('Custom-Header', 'value'); // Custom header const params = new HttpParams().set('page', '1').set('size', '10'); // Query params this.http.get('https://api.example.com/items', { headers, params }).subscribe(response => { console.log(response); // Handle response with headers and params });
You can use HttpClient to easily connect Angular apps to REST APIs by combining the above techniques.
// Example REST API service combining GET and POST @Injectable({ providedIn: 'root' }) export class ApiService { constructor(private http: HttpClient) {} getItems() { return this.http.get<any[]>('https://api.example.com/items'); // Get list of items } addItem(item: any) { return this.http.post('https://api.example.com/items', item); // Add a new item } }
An Angular Module organizes related components, directives, pipes, and services to form cohesive blocks of functionality.
// Example of a basic Angular module import { NgModule } from '@angular/core'; // Import NgModule decorator import { BrowserModule } from '@angular/platform-browser'; // Import BrowserModule import { AppComponent } from './app.component'; // Import root component @NgModule({ declarations: [AppComponent], // Declare components, directives, pipes imports: [BrowserModule], // Import external modules providers: [], // Register services bootstrap: [AppComponent] // Root component to bootstrap }) export class AppModule { }
NgModule decorator accepts metadata that tells Angular how to compile and run module code.
@NgModule({ declarations: [/* Components, directives, pipes */], // What belongs to this module imports: [/* Other modules */], // Modules required by this module providers: [/* Services */], // Services available to this module bootstrap: [/* Root component */] // Entry component for bootstrapping }) export class SomeModule { }
Root module bootstraps the app, feature modules encapsulate specific functionalities.
// Root module example @NgModule({ declarations: [AppComponent], imports: [BrowserModule, FeatureModule], bootstrap: [AppComponent] }) export class AppModule { } // Feature module example @NgModule({ declarations: [FeatureComponent], imports: [], exports: [FeatureComponent] }) export class FeatureModule { }
Shared modules contain common components, directives, and pipes to be reused across other modules.
@NgModule({ declarations: [CommonComponent, CommonDirective], imports: [], exports: [CommonComponent, CommonDirective] }) export class SharedModule { }
Lazy loading improves app startup time by loading modules on demand via the router.
// app-routing.module.ts const routes = [ { path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) } ]; // Feature module loaded only when 'feature' route accessed
CoreModule holds singleton services; SharedModule holds reusable components/directives.
// CoreModule example @NgModule({ providers: [SingletonService], }) export class CoreModule { } // SharedModule example @NgModule({ declarations: [CommonComponent], exports: [CommonComponent] }) export class SharedModule { }
Declarations register components/directives/pipes within a module; imports bring in other modules.
@NgModule({ declarations: [MyComponent, MyDirective], // Register in this module imports: [CommonModule, FormsModule] // Use functionalities from imported modules }) export class MyModule { }
Keep modules focused, use SharedModule for common items, avoid importing CoreModule multiple times.
// Best practice example: Import SharedModule everywhere but CoreModule only once in AppModule @NgModule({ imports: [BrowserModule, SharedModule], // Shared items reusable providers: [], // Core services should be here once bootstrap: [AppComponent] }) export class AppModule { }
RxJS is a reactive programming library that allows handling asynchronous data streams using Observables.
Observables represent a stream of data over time, which can be subscribed to and observed.
// Creating a simple observable import { Observable } from 'rxjs'; const observable = new Observable(observer => { observer.next('Hello'); // Emit value 'Hello' observer.next('World'); // Emit value 'World' observer.complete(); // Mark observable as complete });
You subscribe to start receiving values from an Observable and can unsubscribe to stop.
const subscription = observable.subscribe({ next: value => console.log(value), // Handle emitted values complete: () => console.log('Completed') // Called on completion }); // Later unsubscribe to avoid memory leaks subscription.unsubscribe();
Operators allow transforming, filtering, and combining Observables.
import { of } from 'rxjs'; import { map, filter } from 'rxjs/operators'; of(1, 2, 3, 4).pipe( filter(x => x % 2 === 0), // Only even numbers map(x => x * 10) // Multiply each by 10 ).subscribe(x => console.log(x)); // Output: 20, 40
Subjects act as both an Observable and Observer, allowing multicasting.
import { Subject, BehaviorSubject } from 'rxjs'; const subject = new Subject(); subject.subscribe(value => console.log('Observer 1:', value)); subject.next(1); // Emits 1 to subscribers const behaviorSubject = new BehaviorSubject(0); // Initial value 0 behaviorSubject.subscribe(value => console.log('Behavior Observer:', value)); behaviorSubject.next(2); // Emits 2
Operators like combineLatest
allow combining multiple Observables.
import { combineLatest, of } from 'rxjs'; const obs1 = of('A', 'B'); const obs2 = of(1, 2); combineLatest([obs1, obs2]).subscribe(([val1, val2]) => { console.log(val1, val2); // Logs combined latest values });
Errors can be caught and handled using operators like catchError
.
import { throwError, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; throwError('Error!').pipe( catchError(err => { console.error('Caught error:', err); return of('Fallback value'); // Return fallback observable }) ).subscribe(value => console.log(value)); // Output: Fallback value
Always unsubscribe when no longer needed, use operators for clean code, and handle errors gracefully.
// Use takeUntil or async pipe in Angular templates for automatic unsubscribe // Example: Using async pipe in template // <div *ngIf="observable$ | async as data"> // {{ data }} // </div>
Animations improve user experience by adding smooth transitions and feedback on UI interactions.
Triggers define animation states and when animations run in templates.
import { trigger, state, style, transition, animate } from '@angular/animations'; @Component({ selector: 'app-box', template: ` <div [@boxState]="state" (click)="toggleState()">Click me!</div> `, animations: [ trigger('boxState', [ state('small', style({ transform: 'scale(1)' })), // Small state style state('large', style({ transform: 'scale(1.5)' })), // Large state style transition('small <=> large', animate('300ms ease-in')) // Animate between states ]) ] }) export class BoxComponent { state = 'small'; toggleState() { this.state = this.state === 'small' ? 'large' : 'small'; // Toggle animation state } }
States define styles, transitions define animations between states.
Use style()
inside animate()
to animate CSS properties.
transition('void => *', [ style({ opacity: 0 }), animate(500, style({ opacity: 1 })) // Fade in animation ])
Keyframes allow defining multiple styles at specific offsets during an animation.
import { keyframes } from '@angular/animations'; animate('1s ease-in', keyframes([ style({ opacity: 0, transform: 'translateX(-100%)', offset: 0 }), style({ opacity: 1, transform: 'translateX(15px)', offset: 0.7 }), style({ opacity: 1, transform: 'translateX(0)', offset: 1 }) ]))
group()
runs animations in parallel; sequence()
runs them one after another.
import { group, sequence } from '@angular/animations'; transition('open => closed', [ sequence([ animate('200ms', style({ opacity: 0 })), group([ animate('300ms ease', style({ height: 0 })), animate('300ms ease', style({ padding: 0 })) ]) ]) ])
Listen for animation start and done events in templates or component code.
<div [@boxState]="state" (@boxState.done)="animationDone()">Animate Me</div> animationDone() { console.log('Animation finished!'); }
Define reusable animation functions for consistency across components.
import { animation, style, animate } from '@angular/animations'; export const fadeInAnimation = animation([ style({ opacity: 0 }), animate('{{ duration }} ease-in', style({ opacity: 1 })) ]); @Component({ animations: [ trigger('fadeIn', [ transition(':enter', [ useAnimation(fadeInAnimation, { params: { duration: '500ms' } }) ]) ]) ] })
Testing ensures application reliability and catches bugs early.
Jasmine is a testing framework; Karma runs tests in browsers.
// spec/example.spec.ts describe('Simple Test Suite', () => { // Define a test suite it('should add numbers correctly', () => { // Define a test case expect(1 + 2).toBe(3); // Assert addition works }); });
Test individual Angular components for expected behavior.
// example.component.spec.ts import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ExampleComponent } from './example.component'; describe('ExampleComponent', () => { let component: ExampleComponent; let fixture: ComponentFixture<ExampleComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ ExampleComponent ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create component', () => { expect(component).toBeTruthy(); }); });
Test Angular services in isolation.
// example.service.spec.ts import { TestBed } from '@angular/core/testing'; import { ExampleService } from './example.service'; describe('ExampleService', () => { let service: ExampleService; beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(ExampleService); }); it('should be created', () => { expect(service).toBeTruthy(); }); it('should return expected value', () => { expect(service.getValue()).toBe('expected value'); }); });
Mock HTTP requests to test data fetching.
// example.service.spec.ts (continued) import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [ExampleService] }); service = TestBed.inject(ExampleService); httpMock = TestBed.inject(HttpTestingController); }); it('should fetch data from API', () => { const mockData = { name: 'Test Data' }; service.getData().subscribe(data => { expect(data).toEqual(mockData); }); const req = httpMock.expectOne('api/data'); expect(req.request.method).toBe('GET'); req.flush(mockData); httpMock.verify(); });
Test custom directives and pipes.
// example.pipe.spec.ts import { GreetPipe } from './greet.pipe'; describe('GreetPipe', () => { const pipe = new GreetPipe(); it('transforms "John" to greeting', () => { expect(pipe.transform('John')).toBe('Hello, John!'); }); });
Simulate user behavior to test the whole app.
// protractor.conf.js exports.config = { framework: 'jasmine', specs: ['e2e/**/*.spec.js'], capabilities: { browserName: 'chrome' }, directConnect: true, jasmineNodeOpts: { defaultTimeoutInterval: 30000 } };
Angular Material provides reusable UI components based on Google's Material Design for Angular apps.
// Run Angular CLI command to install Angular Material ng add @angular/material // This installs packages and updates your app module with Material imports automatically
Use Material components like MatToolbar, MatSidenav for navigation and layout.
// app.component.html example <mat-toolbar color="primary"> My Angular Material App </mat-toolbar> <mat-sidenav-container class="example-container"> <mat-sidenav mode="side" opened> Navigation Menu </mat-sidenav> <mat-sidenav-content> Main Content Area </mat-sidenav-content> </mat-sidenav-container>
// Using Material buttons and progress spinner <button mat-raised-button color="accent">Click Me</button> <mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
Material form controls enhance inputs with consistent styling and features.
// Material input example <mat-form-field appearance="fill"> <mat-label>Enter your name</mat-label> <input matInput placeholder="Name"> </mat-form-field>
// Basic Material table with pagination <table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <ng-container matColumnDef="position"> <th mat-header-cell *matHeaderCellDef> No. </th> <td mat-cell *matCellDef="let element"> {{element.position}} </td> </ng-container> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> Name </th> <td mat-cell *matCellDef="let element"> {{element.name}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
Use MatDialog service to open dialogs or modals in Angular Material.
// Inject MatDialog and open a dialog constructor(public dialog: MatDialog) {} openDialog() { this.dialog.open(DialogContentComponent); // Opens dialog component }
Angular Material supports theming with predefined palettes and custom themes via SCSS.
// In styles.scss or theme file @use '@angular/material' as mat; $custom-primary: mat.define-palette(mat.$indigo-palette); $custom-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); $custom-theme: mat.define-light-theme(( color: ( primary: $custom-primary, accent: $custom-accent, ) )); @include mat.all-component-themes($custom-theme);
State management helps maintain and share application state in a predictable way. NgRx is a popular state management library for Angular based on Redux principles.
// Simple state management example // Store holds the state, actions describe changes, reducers apply changes // Define initial state export interface AppState { counter: number; } const initialState: AppState = { counter: 0 };
NgRx Store holds application state in a single immutable tree and dispatches actions to modify it.
import { createStore } from '@ngrx/store'; // Define action type export const increment = '[Counter] Increment'; // Create reducer function export function counterReducer(state = 0, action: any) { switch (action.type) { case increment: return state + 1; // Increase counter by 1 default: return state; // Return unchanged state } }
Actions represent events, reducers update state, and effects handle side effects like API calls.
// Action example import { createAction } from '@ngrx/store'; export const loadItems = createAction('[Items] Load Items'); // Reducer example import { createReducer, on } from '@ngrx/store'; const initialState = { items: [] }; const itemsReducer = createReducer( initialState, on(loadItems, state => ({ ...state, loading: true })) // Set loading true on loadItems action ); // Effect example import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { switchMap, map } from 'rxjs/operators'; @Injectable() export class ItemsEffects { loadItems$ = createEffect(() => this.actions$.pipe( ofType(loadItems), switchMap(() => this.itemsService.getItems() .pipe( map(items => ({ type: '[Items API] Load Success', items })) ) ) )); constructor(private actions$: Actions, private itemsService: ItemsService) {} }
Selectors are pure functions used to select slices of state efficiently.
import { createSelector } from '@ngrx/store'; export const selectItems = (state: any) => state.items; export const selectLoadedItems = createSelector( selectItems, items => items.filter(item => item.loaded) );
Components dispatch actions and subscribe to store state using selectors.
import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; export class ItemsComponent { items$: Observable<any[]>; constructor(private store: Store<any>) { this.items$ = this.store.select(selectLoadedItems); // Subscribe to items slice } load() { this.store.dispatch(loadItems()); // Dispatch load action } }
NgRx DevTools provide time-travel debugging and inspection of store changes.
// Enable DevTools in AppModule imports import { StoreDevtoolsModule } from '@ngrx/store-devtools'; @NgModule({ imports: [ StoreDevtoolsModule.instrument({ maxAge: 25 // Retain last 25 states }) ] }) export class AppModule { }
Use feature modules, facade pattern for cleaner component-store interaction, and entity adapters for collections.
// Facade example @Injectable({ providedIn: 'root' }) export class ItemsFacade { items$ = this.store.select(selectLoadedItems); constructor(private store: Store) {} loadItems() { this.store.dispatch(loadItems()); } }
Keep state minimal, use selectors, avoid side-effects in reducers, keep effects simple and isolated.
// Example best practice comment: // Reducers must be pure functions - no API calls or async tasks here. // Effects should handle all side-effects (like HTTP calls).
Authentication is verifying user identity. Common strategies include form-based, token-based, and OAuth.
// Example: Simple form-based login (conceptual) // User submits username and password // Server verifies credentials and creates session or issues token
Login validates credentials and creates a session/token; logout destroys it.
// Pseudocode for login/logout flow function login(username, password) { if (validateUser(username, password)) { // Create session or JWT token return token; } else { throw new Error('Invalid credentials'); } } function logout() { // Destroy session or invalidate token }
JSON Web Tokens (JWT) are used to securely transmit user identity and claims.
// Example JWT creation (Node.js) const jwt = require('jsonwebtoken'); const payload = { userId: 123 }; const secret = 'yourSecretKey'; // Sign JWT token const token = jwt.sign(payload, secret, { expiresIn: '1h' }); // Verify JWT token jwt.verify(token, secret, (err, decoded) => { if (err) { console.error('Invalid token'); } else { console.log('Decoded payload:', decoded); } });
In Angular, route guards protect routes based on auth state.
// Example of AuthGuard in Angular import { Injectable } from '@angular/core'; import { CanActivate, Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate(): boolean { const loggedIn = !!localStorage.getItem('token'); if (!loggedIn) { this.router.navigate(['/login']); return false; } return true; } }
Auth state can be stored in localStorage, sessionStorage, or a state management library.
// Save token in localStorage after login localStorage.setItem('token', 'jwt-token-value'); // Retrieve token for use const token = localStorage.getItem('token'); // Remove token on logout localStorage.removeItem('token');
Control access by user roles, restricting features or routes accordingly.
// Example roles check const userRole = 'admin'; // from token or backend if (userRole === 'admin') { // show admin features } else { // restrict access }
Use HTTP interceptors to automatically add JWT tokens to HTTP requests.
// Angular HTTP interceptor example import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; @Injectable() export class TokenInterceptor implements HttpInterceptor { intercept(req, next) { const token = localStorage.getItem('token'); if (token) { const cloned = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); return next.handle(cloned); } return next.handle(req); } }
OAuth enables login via third-party providers like Google or Facebook.
// Example: redirect to OAuth provider login const googleAuthUrl = 'https://accounts.google.com/o/oauth2/auth?...'; // On button click, redirect user window.location.href = googleAuthUrl; // After redirect, backend exchanges code for access token
Use Angular's HttpClient to upload files to a server.
// Template for file input <input type="file" (change)="onFileSelected($event)" /> // Component code onFileSelected(event: any) { const file: File = event.target.files[0]; // Get selected file const formData = new FormData(); // Create FormData object formData.append('file', file); // Append file to FormData this.http.post('/upload', formData).subscribe(response => { console.log('Upload successful', response); // Log upload response }); }
Show upload progress using HttpClient's reportProgress option.
const req = new HttpRequest('POST', '/upload', formData, { reportProgress: true // Enable progress events }); this.http.request(req).subscribe(event => { if (event.type === HttpEventType.UploadProgress) { const percentDone = Math.round(100 * event.loaded / event.total!); // Calculate progress percentage console.log(`File is ${percentDone}% uploaded.`); } else if (event instanceof HttpResponse) { console.log('Upload complete'); } });
Implement drag-and-drop to enhance UX.
<div class="drop-zone" (drop)="onDrop($event)" (dragover)="onDragOver($event)"> Drag and drop files here </div> onDragOver(event: DragEvent) { event.preventDefault(); // Allow drop } onDrop(event: DragEvent) { event.preventDefault(); const files = event.dataTransfer?.files; // Get dropped files if (files?.length) { this.uploadFiles(files); } }
Restrict accepted file types for upload.
<input type="file" accept=".png,.jpg,.jpeg" (change)="onFileSelected($event)" />
Trigger file downloads from server responses.
this.http.get('/download/file.pdf', { responseType: 'blob' }).subscribe(blob => { const url = window.URL.createObjectURL(blob); // Create URL for blob const a = document.createElement('a'); a.href = url; a.download = 'file.pdf'; // Set download filename a.click(); window.URL.revokeObjectURL(url); // Clean up URL object });
Handle binary large objects for files.
const blob = new Blob([data], { type: 'application/pdf' }); // Create Blob from data const url = URL.createObjectURL(blob); // Create URL for Blob window.open(url); // Open Blob in new tab
Upload files to Firebase Storage using AngularFire.
const file = event.target.files[0]; const filePath = `uploads/${file.name}`; const task = this.storage.upload(filePath, file); task.snapshotChanges().subscribe(snapshot => { // Monitor upload progress here }); task.then(() => { console.log('Upload to Firebase complete'); });
Internationalization (i18n) is the process of designing your app to support multiple languages and regions.
Angular provides built-in i18n support for translating templates and managing locales.
<h1 i18n>Welcome to our Application!</h1>
Use Angular CLI to extract messages and create translation files.
// Extract messages to messages.xlf ng extract-i18n --output-path src/locale // Example translation in messages.fr.xlf <trans-unit id="welcomeMessage" datatype="html"> <source>Welcome to our Application!</source> <target>Bienvenue dans notre application!</target> </trans-unit>
Set the locale in your app module or during build time to support different languages.
// app.module.ts import { registerLocaleData } from '@angular/common'; import localeFr from '@angular/common/locales/fr'; registerLocaleData(localeFr, 'fr');
Angular pipes automatically adapt date and currency formatting based on locale.
<p>{{ today | date:'fullDate' }}</p> <p>{{ price | currency:'EUR' }}</p>
For runtime translation changes, use libraries like ngx-translate.
// app.module.ts import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { HttpClient } from '@angular/common/http'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http); } @NgModule({ imports: [ TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }) ], }) export class AppModule { }
<!-- app.component.html --> <h1>{{ 'HOME.TITLE' | translate }}</h1>
Angular uses change detection to update the DOM when data changes. Default strategy checks everything; OnPush optimizes this.
// Using OnPush change detection strategy in a component <!-- app.component.ts --> import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', changeDetection: ChangeDetectionStrategy.OnPush // Optimize change detection }) export class AppComponent { title = 'performance-app'; // Component property }
OnPush tells Angular to check component only when inputs change or events occur, improving performance.
// Usage example of OnPush in a child component import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-child', template: '<p>Child: {{data}}</p>', changeDetection: ChangeDetectionStrategy.OnPush // Set OnPush strategy }) export class ChildComponent { @Input() data!: string; // Input data from parent }
Load feature modules only when needed to reduce initial load time.
// app-routing.module.ts example for lazy loading const routes: Routes = [ { path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) // Lazy load FeatureModule } ];
Analyze bundle size to optimize dependencies using tools like Webpack Bundle Analyzer.
// Run Angular build with stats json ng build --stats-json // Then analyze with source-map-explorer or webpack-bundle-analyzer npx source-map-explorer dist/performance-app/main.*.js
Remove unused code from bundles automatically during build.
// Angular CLI uses Webpack tree shaking by default on production builds ng build --prod
Compile templates during build instead of runtime for faster startup.
// Enable AOT compilation in Angular CLI ng build --prod --aot
Use Angular Service Worker for caching assets and API calls to improve performance.
// Add Angular PWA package ng add @angular/pwa // This configures service worker for caching static assets automatically
Split your app code into smaller chunks loaded on demand to improve load time.
// Using dynamic imports for code splitting import('./lazy/lazy.module').then(m => m.LazyModule)
A Progressive Web App (PWA) is a web app that uses modern web capabilities to deliver an app-like experience to users. PWAs are reliable, fast, and engaging.
Use Angular CLI to add PWA support easily to your Angular app.
# Run this command in your Angular project root ng add @angular/pwa
Service Workers act as a network proxy to manage caching and offline functionality.
<!-- In angular.json ensure serviceWorker is enabled --> "serviceWorker": true, "ngswConfigPath": "ngsw-config.json"
The manifest file defines the appearance of the app on devices (icon, name, theme color).
{ "name": "My Angular PWA", "short_name": "AngularPWA", "theme_color": "#1976d2", "background_color": "#fafafa", "display": "standalone", "scope": "/", "start_url": "/", "icons": [ { "src": "assets/icons/icon-72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "assets/icons/icon-96x96.png", "sizes": "96x96", "type": "image/png" } ] }
Define caching strategies in ngsw-config.json for efficient resource caching.
{ "index": "/index.html", "assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/*.css", "/*.js" ] } }, { "name": "assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "files": [ "/assets/**" ] } } ] }
With service worker and caching, the app works offline by serving cached resources.
// No additional code needed, service worker caches resources automatically after installation
Push Notifications notify users even when the app is not active.
import { SwPush } from '@angular/service-worker'; constructor(private swPush: SwPush) {} subscribeToNotifications() { this.swPush.requestSubscription({ serverPublicKey: 'YOUR_PUBLIC_VAPID_KEY' }).then(sub => { console.log('Notification subscription:', sub); // Send subscription to your server }).catch(err => console.error('Could not subscribe to notifications', err)); }
Build your Angular app for production and deploy it on a web server that supports HTTPS.
ng build --prod # Deploy the contents of the dist folder to your web server (e.g., Apache, Nginx)
Firebase is a cloud platform offering real-time database, authentication, storage, and hosting.
// Example Firebase config (environment.ts) export const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "your-app.firebaseapp.com", projectId: "your-app-id", storageBucket: "your-app.appspot.com", messagingSenderId: "SENDER_ID", appId: "APP_ID" };
AngularFire is the official Angular library to interact with Firebase services.
// Install AngularFire & Firebase // npm install firebase @angular/fire // Import AngularFireModule in app.module.ts import { AngularFireModule } from '@angular/fire/compat'; import { environment } from '../environments/environment'; @NgModule({ imports: [ AngularFireModule.initializeApp(environment.firebaseConfig), // other imports ], }) export class AppModule {}
AngularFire allows real-time data syncing with Firebase Realtime Database.
// Inject AngularFireDatabase and listen to data import { AngularFireDatabase } from '@angular/fire/compat/database'; constructor(private db: AngularFireDatabase) {} getItems() { return this.db.list('items').valueChanges(); }
Firestore is Firebase’s scalable NoSQL cloud database.
// Inject AngularFirestore and query collection import { AngularFirestore } from '@angular/fire/compat/firestore'; constructor(private firestore: AngularFirestore) {} getUsers() { return this.firestore.collection('users').valueChanges(); }
Authenticate users via email/password or social providers using AngularFireAuth.
// Inject AngularFireAuth import { AngularFireAuth } from '@angular/fire/compat/auth'; constructor(private afAuth: AngularFireAuth) {} login(email: string, password: string) { return this.afAuth.signInWithEmailAndPassword(email, password); } logout() { return this.afAuth.signOut(); }
Upload and download files using Firebase Storage integration.
// Inject AngularFireStorage import { AngularFireStorage } from '@angular/fire/compat/storage'; constructor(private storage: AngularFireStorage) {} uploadFile(file: File) { const filePath = 'uploads/' + file.name; const ref = this.storage.ref(filePath); return ref.put(file); }
Deploy Angular apps to Firebase Hosting for fast, secure delivery.
// Steps: // 1. Install Firebase CLI: npm install -g firebase-tools // 2. Login: firebase login // 3. Initialize project: firebase init hosting // 4. Build Angular app: ng build --prod // 5. Deploy: firebase deploy
Define Firebase security rules and monitor app usage in Firebase console.
// Example Firestore security rule allowing read to authenticated users service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
Load components dynamically at runtime using ComponentFactoryResolver.
// Template: placeholder for dynamic component <ng-template #container></ng-template> // Component code @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef; loadComponent(component: Type<any>) { this.container.clear(); // Clear previous component const factory = this.cfr.resolveComponentFactory(component); // Resolve component factory this.container.createComponent(factory); // Create component dynamically }
Insert external content into a component using <ng-content>.
// Child component template <div class="card"> <ng-content></ng-content> <!-- Project content here --> </div> // Usage <app-child> <p>Projected content here</p> </app-child>
Create your own decorators for classes, properties, or methods.
// Custom method decorator example function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${propertyKey} with`, args); return original.apply(this, args); }; } // Usage in component @Log myMethod(arg: any) { console.log('Method body', arg); }
Manipulate DOM elements safely using Renderer2 and ElementRef.
constructor(private el: ElementRef, private renderer: Renderer2) {} ngOnInit() { this.renderer.setStyle(this.el.nativeElement, 'color', 'blue'); // Set style dynamically }
Manually control change detection in components.
constructor(private cd: ChangeDetectorRef) {} someMethod() { // Update data then detect changes manually this.data = 'new value'; this.cd.detectChanges(); }
Offload heavy computations to background threads.
// Create worker: ng generate web-worker app if (typeof Worker !== 'undefined') { const worker = new Worker(new URL('./app.worker', import.meta.url)); worker.onmessage = ({ data }) => { console.log('Worker response:', data); }; worker.postMessage('start'); }
Enable server-side rendering for faster load times and SEO.
// Install Angular Universal ng add @nguniversal/express-engine // Build and serve SSR app npm run build:ssr npm run serve:ssr
Split frontend app into smaller, independently deployable apps.
// Use module federation or other techniques to load micro frontends dynamically. // Example: Angular Module Federation plugin setup (simplified) const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'app1', filename: 'remoteEntry.js', exposes: { './Component': './src/app/some.component.ts', }, shared: ['@angular/core', '@angular/common', '@angular/router'], }), ], };
Use Angular CLI to build your project for production.
// Command to build Angular app for production optimization ng build --prod
Angular supports multiple environment files for different setups.
// src/environments/environment.prod.ts export const environment = { production: true, apiUrl: 'https://api.production.com' };
Steps to deploy Angular app to Firebase Hosting:
// Install Firebase CLI globally npm install -g firebase-tools // Login to Firebase firebase login // Initialize Firebase in your Angular project firebase init // Build your app ng build --prod // Deploy to Firebase Hosting firebase deploy
Use Netlify or Vercel for easy continuous deployment from GitHub repositories.
// After building Angular app with 'ng build --prod', upload 'dist' folder contents to Netlify or Vercel. // Alternatively, connect your GitHub repo for automatic deploys.
Automate build and deployment with GitHub Actions.
<!-- .github/workflows/angular-deploy.yml --> name: Angular CI/CD on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm install - name: Build run: npm run build -- --prod - name: Deploy to Firebase uses: w9jds/firebase-action@v1 with: args: deploy --only hosting env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
Containerize your Angular app with Docker.
# Dockerfile for Angular app FROM node:16-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build --prod FROM nginx:alpine COPY --from=build-stage /app/dist/your-app-name /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
Use tools like Sentry or LogRocket for tracking runtime errors and performance.
Use Git for version control and collaborate effectively.
// Basic Git commands git init // Initialize Git repo git add . // Stage all files for commit git commit -m "Initial commit" // Commit with message git remote add origin https://github.com/username/repo.git // Add remote repo git push -u origin main // Push changes to remote main branch
A fully functional online store with product listings, cart, checkout, and payment integration.
<?php // Simple product array example $products = [ ['id' => 1, 'name' => 'Laptop', 'price' => 999.99], ['id' => 2, 'name' => 'Smartphone', 'price' => 599.99] ]; // Display products foreach ($products as $product) { echo '<div>'; echo '<h2>' . $product['name'] . '</h2>'; // Product name echo '<p>Price: $' . $product['price'] . '</p>'; // Product price echo '</div>'; } ?>
Dashboard displaying metrics such as followers, likes, and posts with data visualization.
<?php // Sample data array for followers $socialData = [ 'followers' => 1200, 'likes' => 3400, 'posts' => 150 ]; // Output social metrics echo '<ul>'; foreach ($socialData as $metric => $value) { echo '<li>' . ucfirst($metric) . ': ' . $value . '</li>'; // Metric with value } echo '</ul>'; ?>
Basic chat interface with user messages displayed live (using polling or WebSocket in full app).
<?php // Example of storing messages in session for simplicity session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Add new message $_SESSION['messages'][] = $_POST['message']; } // Display messages if (!empty($_SESSION['messages'])) { foreach ($_SESSION['messages'] as $msg) { echo '<p>' . htmlspecialchars($msg) . '</p>'; // Display safe message } } ?> <form method="POST"> <input type="text" name="message" placeholder="Enter message"> <button type="submit">Send</button> </form>
Manage to-do tasks with add, delete, and mark complete functionality.
<?php session_start(); // Initialize tasks array if (!isset($_SESSION['tasks'])) { $_SESSION['tasks'] = []; } // Add task if (!empty($_POST['task'])) { $_SESSION['tasks'][] = $_POST['task']; } // Display tasks echo '<ul>'; foreach ($_SESSION['tasks'] as $index => $task) { echo '<li>' . htmlspecialchars($task) . '</li>'; } echo '</ul>'; ?> <form method="POST"> <input type="text" name="task" placeholder="New task"> <button type="submit">Add Task</button> </form>
Shows weather info for a user-selected location (simple example with static data).
<?php // Sample static weather data $weather = [ 'city' => 'New York', 'temperature' => '22°C', 'condition' => 'Sunny' ]; // Display weather info echo '<h3>Weather in ' . $weather['city'] . '</h3>'; echo '<p>Temperature: ' . $weather['temperature'] . '</p>'; echo '<p>Condition: ' . $weather['condition'] . '</p>'; ?>
List jobs with details and filtering options (simple static example below).
<?php // Static array of jobs $jobs = [ ['title' => 'Frontend Developer', 'location' => 'Remote', 'type' => 'Full-time'], ['title' => 'Backend Developer', 'location' => 'NYC', 'type' => 'Part-time'] ]; // Display jobs foreach ($jobs as $job) { echo '<div>'; echo '<h4>' . $job['title'] . '</h4>'; echo '<p>' . $job['location'] . ' - ' . $job['type'] . '</p>'; echo '</div>'; } ?>
Simple portfolio showcasing projects with images and descriptions.
<?php // Example projects array $projects = [ ['name' => 'Project One', 'desc' => 'Description of project one.'], ['name' => 'Project Two', 'desc' => 'Description of project two.'] ]; // Display projects foreach ($projects as $project) { echo '<section>'; echo '<h2>' . $project['name'] . '</h2>'; echo '<p>' . $project['desc'] . '</p>'; echo '</section>'; } ?>
Prepare a presentation highlighting your final capstone project achievements.
No code example needed here.
Angular apps can be enhanced by integrating AI technologies to provide smarter, more interactive experiences.
AI technologies include machine learning, NLP, computer vision, and more.
AI integration enables powerful features like chatbots, recommendations, and predictive analytics within Angular apps.
// Install Angular CLI globally if not installed npm install -g @angular/cli // Create new Angular project ng new ai-angular-project // Navigate to project folder cd ai-angular-project // Serve the app locally ng serve
Use Angular HttpClient to connect to AI APIs providing RESTful endpoints.
<!-- Import HttpClientModule in app.module.ts --> import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, // Enables HttpClient for API calls ], }) export class AppModule { } // Example service calling AI API import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AiService { constructor(private http: HttpClient) {} getAiResponse(input: string) { // Replace with real AI API endpoint return this.http.post('https://api.ai-service.com/respond', { prompt: input }); } }
Secure your API calls using keys or OAuth tokens.
// Sample code to call OpenAI API in Angular service import { HttpClient, HttpHeaders } from '@angular/common/http'; const OPENAI_API_KEY = 'your_api_key_here'; const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${OPENAI_API_KEY}` }); const body = { model: "text-davinci-003", prompt: "Hello AI, how are you?", max_tokens: 50 }; this.http.post('https://api.openai.com/v1/completions', body, { headers }).subscribe(response => { console.log(response); });
Google Cloud offers Vision API, NLP API, and more accessible via REST and client libraries.
Azure provides AI APIs like Text Analytics, Computer Vision, and Speech Services.
IBM Watson offers various AI services like conversation, language translation, and visual recognition.
Build interactive AI chatbots using Angular components and AI backends.
<div class="chat-container"> <div *ngFor="let message of messages"> <p>{{message.user}}: {{message.text}}</p> </div> <input [(ngModel)]="userInput" placeholder="Type your message..." /> <button (click)="sendMessage()">Send</button> </div> <!-- Component.ts --> messages = []; userInput = ''; sendMessage() { this.messages.push({ user: 'User', text: this.userInput }); // Call AI service here and push response this.aiService.getAiResponse(this.userInput).subscribe((res: any) => { this.messages.push({ user: 'AI', text: res.answer }); }); this.userInput = ''; }
Use Dialogflow's REST API or SDK to integrate conversational AI in Angular.
Integrate NLP APIs for text analysis, entity recognition, sentiment analysis, etc.
Call AI sentiment APIs to analyze user input and display feedback.
Use APIs like Google Vision or Azure Computer Vision for image classification in Angular apps.
// Install TensorFlow.js npm install @tensorflow/tfjs // Example: Load and use a pre-trained model in component import * as tf from '@tensorflow/tfjs'; async function loadModel() { const model = await tf.loadLayersModel('/assets/model.json'); const prediction = model.predict(tf.tensor2d([/* input data */], [1, inputSize])); console.log(prediction); }
Leverage TensorFlow.js or ONNX.js to run models directly in the browser.
Host AI models on cloud or servers and access via REST APIs from Angular.
Use WebSockets for live AI data streams like chat or predictions.
Integrate recommendation engines to personalize user experience.
Use Web Speech API or cloud services for voice input processing.
Implement speech synthesis to read content aloud.
Convert spoken words into text for commands or input fields.
Use AI APIs or TensorFlow.js for facial recognition features.
Analyze data patterns to forecast future trends within Angular apps.
Use AI to understand and optimize user interaction.
Deliver personalized content using AI-driven insights.
Enhance search capabilities with AI-powered ranking and filtering.
Implement real-time AI-based processing for media files.
Prepare and clean data for AI workflows.
Detect fraudulent activity by analyzing behavioral patterns.
Use AI for diagnostics, patient monitoring, and more.
Enable live language translation features.
Improve app accessibility with AI tools like speech-to-text and image description.
Create dashboards that visualize AI insights in real time.
Build chatbots that understand conversation context for better interactions.
Implement UI for retraining or updating AI models dynamically.
Display AI predictions and insights using charts and graphs.
Use AI to validate, auto-fill, or suggest input in forms.
Leverage AI tools to improve testing coverage and efficiency.
Apply AI to monitor and enhance app performance.
Use AI for threat detection and enhanced security features.
Address privacy, bias, and fairness when integrating AI.
Monitor usage and control costs of AI API calls.
Track API performance and errors to ensure reliability.
Strategies for troubleshooting AI-related issues.
Explore upcoming innovations combining AI and Angular.
Apply all concepts by building a complete AI-powered Angular app.
Setting up Angular for AI Projects
npm install -g @angular/cli ng new ai-angular-project cd ai-angular-project ng serve
Working with RESTful AI APIs - Simple Angular HttpClient GET request example:
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AiApiService { constructor(private http: HttpClient) {} getAiData() { return this.http.get('https://api.example.com/ai-endpoint'); } }
Calling AI APIs with Angular HttpClient
// ai.service.ts import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AiService { constructor(private http: HttpClient) {} getAiResponse(prompt: string) { return this.http.post('https://api.example.com/ai', { prompt }); } }
Authentication for AI Services (API Keys, OAuth)
import { HttpClient, HttpHeaders } from '@angular/common/http'; const headers = new HttpHeaders({ 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }); this.http.post('https://api.secureai.com/data', { data: 'test' }, { headers }).subscribe(response => { console.log(response); });
Using OpenAI API with Angular
import { HttpClient, HttpHeaders } from '@angular/common/http'; const OPENAI_API_KEY = 'your_openai_api_key'; const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${OPENAI_API_KEY}` }); const body = { model: 'text-davinci-003', prompt: 'Say hello', max_tokens: 5 }; this.http.post('https://api.openai.com/v1/completions', body, { headers }).subscribe(response => { console.log('OpenAI Response:', response); });
Integrating Google Cloud AI Services -Calling Google Vision API to analyze an image:
const headers = new HttpHeaders({ 'Authorization': 'Bearer YOUR_GOOGLE_API_KEY', 'Content-Type': 'application/json' }); const body = { requests: [ { image: { content: 'base64_image_string' }, features: [{ type: 'LABEL_DETECTION', maxResults: 5 }] } ] }; this.http.post('https://vision.googleapis.com/v1/images:annotate', body, { headers }).subscribe(res => { console.log('Google Vision API result', res); });
Using Microsoft Azure Cognitive Services - Text sentiment analysis request example:
const headers = new HttpHeaders({ 'Ocp-Apim-Subscription-Key': 'YOUR_AZURE_KEY', 'Content-Type': 'application/json' }); const body = { documents: [ { id: '1', language: 'en', text: 'I love Angular and AI integration!' } ] }; this.http.post('https://YOUR_REGION.api.cognitive.microsoft.com/text/analytics/v3.0/sentiment', body, { headers }).subscribe(res => { console.log('Azure Sentiment:', res); });
IBM Watson Integration Basics - Using Watson Assistant API
const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Basic ' + btoa('apikey:YOUR_WATSON_APIKEY') }); const body = { input: { text: 'Hello Watson' } }; this.http.post('https://api.us-south.assistant.watson.cloud.ibm.com/v2/assistants/YOUR_ASSISTANT_ID/sessions/YOUR_SESSION_ID/message?version=2021-06-14', body, { headers }).subscribe(res => { console.log('Watson response:', res); });
Chatbots in Angular: Overview -Simple UI skeleton:
<div> <div *ngFor="let msg of messages"> <p><strong>{{ msg.sender }}:</strong> {{ msg.text }}</p> </div> <input [(ngModel)]="userInput" /> <button (click)="send()">Send</button> </div>
Building a Simple AI Chatbot UI
// app.component.ts messages = [ ]; userInput = ''; send() { this.messages.push({ sender: 'User', text: this.userInput }); // Simulated AI response setTimeout(() => { this.messages.push({ sender: 'AI', text: 'You said: ' + this.userInput }); }, 1000); this.userInput = ''; }
Connecting Angular to Dialogflow
// Use Dialogflow REST API const headers = new HttpHeaders({ 'Authorization': 'Bearer YOUR_DIALOGFLOW_ACCESS_TOKEN', 'Content-Type': 'application/json' }); const body = { queryInput: { text: { text: 'Hi', languageCode: 'en' } } }; this.http.post('https://dialogflow.googleapis.com/v2/projects/YOUR_PROJECT_ID/agent/sessions/123456:detectIntent', body, { headers }).subscribe(res => { console.log('Dialogflow Response:', res); });
Natural Language Processing (NLP) APIs Integration
// Example using a dummy NLP API for entity extraction this.http.post('https://api.example.com/nlp/entities', { text: 'Angular AI example' }).subscribe(res => { console.log('Entities:', res); });
Sentiment Analysis with AI APIs
const text = 'I love this Angular AI integration!'; this.http.post('https://api.sentiment.com/analyze', { text }).subscribe((res: any) => { console.log('Sentiment score:', res.score); });
Image Recognition and AI APIs
const imageBase64 = '...'; // base64 image string const body = { image: imageBase64 }; this.http.post('https://api.imagerecognition.com/recognize', body).subscribe(res => { console.log('Image labels:', res); });
Integrating TensorFlow.js with Angular
import * as tf from '@tensorflow/tfjs'; async function predict() { const model = await tf.loadLayersModel('/assets/model.json'); const input = tf.tensor2d([[5.0, 3.0]]); const prediction = model.predict(input) as tf.Tensor; prediction.print(); }
. Running Pretrained Models in Angular - Loading MobileNet pretrained model:
import * as mobilenet from '@tensorflow-models/mobilenet'; async function classifyImage(imgElement: HTMLImageElement) { const model = await mobilenet.load(); const predictions = await model.classify(imgElement); console.log('Predictions:', predictions); }
Custom AI Model Hosting and Access - Calling your custom hosted model API:
this.http.post('https://yourserver.com/model/predict', { inputData: [1,2,3] }).subscribe(res => { console.log('Model output:', res); });
Using WebSockets for Real-Time AI Data
const socket = new WebSocket('wss://ai-server.com/socket'); socket.onopen = () => { socket.send(JSON.stringify({ query: 'Analyze this in real-time' })); }; socket.onmessage = (event) => { console.log('Real-time AI data:', event.data); };
AI-Powered Recommendations in Angular
this.http.get('https://api.example.com/recommendations?userId=123').subscribe(res => { this.recommendations = res; });
Voice Recognition Integration
const recognition = new (window as any).webkitSpeechRecognition(); recognition.onresult = (event) => { console.log('Voice recognized:', event.results[0][0].transcript); }; recognition.start();
Text-to-Speech in Angular Apps
const utterance = new SpeechSynthesisUtterance('Hello from Angular AI app!'); speechSynthesis.speak(utterance);
Speech-to-Text Integration - Same Web Speech API for speech to text.
const recognition = new (window as any).webkitSpeechRecognition(); recognition.onresult = (event) => { console.log('Voice recognized:', event.results[0][0].transcript); }; recognition.start();
same as ''Voice Recognition Integration''
Facial Recognition with face-api.js in Angular
// Import required modules for facial recognition
import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import * as faceapi from 'face-api.js';
@Component({
selector: 'app-face-detection',
template: `<video #video width="720" height="560" autoplay muted></video>`,
})
export class FaceDetectionComponent implements AfterViewInit {
// Reference to the video element
@ViewChild('video') videoRef!: ElementRef;<br> // Load face-api.js models after view init
async ngAfterViewInit() {
// Load models from assets
await faceapi.nets.tinyFaceDetector.loadFromUri('/assets/models');
await faceapi.nets.faceLandmark68Net.loadFromUri('/assets/models');
await faceapi.nets.faceRecognitionNet.loadFromUri('/assets/models');
// Start webcam
this.startVideo();
}
// Function to start webcam and detect faces
startVideo() {
navigator.mediaDevices.getUserMedia({ video: {} })
.then(stream => {
this.videoRef.nativeElement.srcObject = stream;
this.detectFaces();
});
}
// Function to detect faces using face-api
detectFaces() {
this.videoRef.nativeElement.addEventListener('play', () => {
const canvas = faceapi.createCanvasFromMedia(this.videoRef.nativeElement);
document.body.append(canvas);
const displaySize = {
width: this.videoRef.nativeElement.width,
height: this.videoRef.nativeElement.height
};
faceapi.matchDimensions(canvas, displaySize);
// Run detection at interval
setInterval(async () => {
const detections = await faceapi.detectAllFaces(
this.videoRef.nativeElement,
new faceapi.TinyFaceDetectorOptions()
);
const resized = faceapi.resizeResults(detections, displaySize);
canvas.getContext('2d')?.clearRect(0, 0, canvas.width, canvas.height);
faceapi.draw.drawDetections(canvas, resized);
}, 100);
});
}
}
Sending Data to a Predictive Model API and Displaying Predictions
// Import HttpClient and necessary modules
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-predictive-analytics',
template: `<div><button (click)="makePrediction()">Predict</button>
<p *ngIf="prediction">Prediction: {{ prediction }}</p></div>`,
})
export class PredictiveAnalyticsComponent {
// Store the prediction result
prediction: string = '';
// Inject HttpClient via constructor
constructor(private http: HttpClient) {}
// Function to call the AI prediction API
makePrediction() {
// Example input data
const inputData = {
age: 30,
income: 50000,
spendingScore: 75
};
// POST the data to a mock predictive analytics API
this.http.post<any>('https://api.example.com/predict', inputData)
.subscribe(response => {
// Handle and display the predicted result
this.prediction = response.prediction;
}, error => {
console.error('Prediction API error:', error);
});
}
}
Mock API Response (JSON):
{ "prediction": "High Likelihood of Purchase" }
Tracking Click Behavior and Sending to AI Analytics API
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-user-behavior',
template: `<button (click)="trackBehavior('clicked-button')">Click Me</button>`
})
export class UserBehaviorComponent {
constructor(private http: HttpClient) {}
// Simulates sending user behavior to an AI-powered analytics API
trackBehavior(action: string) {
const behaviorData = {
userId: '12345',
action: action,
timestamp: new Date()
};
// POST the data to an analytics API
this.http.post('https://api.example.com/user-behavior', behaviorData)
.subscribe(response => {
console.log('Behavior sent:', response);
});
}
}
Load Personalized Content Based on AI Response
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-personalized-content',<br> template: `<h2>Welcome, {{ personalizedMessage }}</h2>`<br> })<br> export class PersonalizedComponent {<br> personalizedMessage = '';<br> constructor(private http: HttpClient) {<br> this.loadPersonalization();<br> }<br> // Sends user profile to an AI API and receives custom content<br> loadPersonalization() {<br> const userProfile = {<br> name: 'Alice',<br> preferences: ['books', 'technology']<br> };<br> this.http.post<any>('https://api.example.com/personalize', userProfile)<br> .subscribe(response => {<br> this.personalizedMessage = response.message;<br> });<br> }<br> }<br>
Angular Component Using AI Search API
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-ai-search',<br> template: `<input [(ngModel)]="query" placeholder="Search"/><br> <button (click)="search()">Search</button><br> <ul><li *ngFor="let result of results">{{ result }}</li></ul>`<br> })<br> export class AiSearchComponent {<br> query = '';<br> results: string[ ] = [ ];<br> constructor(private http: HttpClient) {}<br> // Sends the query to an AI API for search processing<br> search() {<br> this.http.post<any>('https://api.example.com/ai-search', { query: this.query })<br> .subscribe(response => {<br> this.results = response.results;<br> });<br> }<br> }<br>
Upload Image and Process via AI API
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-image-ai',<br> template: `<input type="file" (change)="uploadImage($event)">`<br> })<br> export class ImageAIComponent {<br> constructor(private http: HttpClient) {}<br> uploadImage(event: any) {<br> const file = event.target.files[0];<br> const formData = new FormData();<br> formData.append('image', file);<br> // Send the image to an AI processing API<br> this.http.post('https://api.example.com/image-analyze', formData)<br> .subscribe(res => console.log('AI response:', res));<br> }<br> }<br>
Normalize Numeric Data
const rawData = [5, 10, 15, 20];
const min = Math.min(...rawData);
const max = Math.max(...rawData);
// Normalize data to [0, 1]
const normalized = rawData.map(val => (val - min) / (max - min));
console.log('Normalized Data:', normalized);
Integrating AI for Fraud Detection - Send Transaction to AI for Fraud Scoring
import { HttpClient } from '@angular/common/http';<br> import { Component } from '@angular/core';<br> @Component({<br> selector: 'app-fraud-check',<br> template: `<button (click)="checkFraud()">Check Transaction</button>`<br> })<br> export class FraudDetectionComponent {<br> constructor(private http: HttpClient) {}<br> checkFraud() {<br> const transaction = { amount: 2000, location: 'Unknown', userId: '9876' };<br> this.http.post<any>('https://api.example.com/fraud-check', transaction)<br> .subscribe(result => console.log('Fraud Score:', result.score));<br> }<br> }<br>
AI in Angular for Medical Applications - Send Symptoms to AI Diagnostic API
const symptoms = ['fever', 'cough', 'fatigue'];<br> fetch('https://api.medical-ai.com/diagnose', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ symptoms })<br> })<br> .then(res => res.json())<br> .then(data => console.log('Diagnosis:', data));<br>
Translate User Input to French - Real time translation
import { HttpClient } from '@angular/common/http';<br> import { Component } from '@angular/core';<br> @Component({<br> selector: 'app-translate',<br> template: `<input [(ngModel)]="text" /><button (click)="translate()">Translate</button><p>{{ result }}</p>`<br> })<br> export class TranslateComponent {<br> text = '';<br> result = '';<br> constructor(private http: HttpClient) {}<br> translate() {<br> this.http.post<any>('https://api.example.com/translate', { text: this.text, targetLang: 'fr' })<br> .subscribe(res => this.result = res.translatedText);<br> }<br> }<br>
AI-Powered Accessibility Features - Describe Image for Visually Impaired Users
const imageUrl = 'https://example.com/dog.jpg';<br> fetch('https://api.example.com/image-caption', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ url: imageUrl })<br> })<br> .then(res => res.json())<br> .then(data => console.log('AI Description:', data.caption));<br>
Building AI-Driven Dashboards - Fetch Prediction Data and Visualize
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-dashboard',<br> template: `<h2>Predicted Sales: {{ prediction }}</h2>`<br> })<br> export class DashboardComponent {<br> prediction = 0;<br> constructor(private http: HttpClient) {<br> this.getPrediction();<br> }<br> getPrediction() {<br> this.http.get<any>('https://api.example.com/predict-sales')<br> .subscribe(data => this.prediction = data.value);<br> }<br> }<br>
AI Chatbots with Context Awareness - Send Chat + Context to AI Bot
const context = [<br> { role: 'user', message: 'What is Angular?' },<br> { role: 'bot', message: 'Angular is a framework for building SPAs.' }<br> ];<br> const newMessage = 'How do I install it?';<br> fetch('https://api.example.com/chat', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ context, message: newMessage })<br> })<br> .then(res => res.json())<br> .then(data => console.log('Bot Reply:', data.reply));<br>
Training and Updating AI Models via Angular - You can provide Angular UI for users to upload new training data and trigger model updates.
- Upload CSV to Trigger Retraining
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-train-model',<br> template: `<input type="file" (change)="uploadData($event)">`<br> })<br> export class TrainModelComponent {<br> constructor(private http: HttpClient) {}<br> uploadData(event: any) {<br> const file = event.target.files[0];<br> const formData = new FormData();<br> formData.append('file', file);<br> this.http.post('https://api.example.com/train-model', formData)<br> .subscribe(res => console.log('Model training started', res));<br> }<br> }<br>
Handling AI Model Results and Visualization - Once the AI model sends back results, you can display them using charts, tables, or cards. Example: Show Confidence Score and Outcome
import { Component } from '@angular/core';<br> import { HttpClient } from '@angular/common/http';<br> @Component({<br> selector: 'app-result-display',<br> template: `<p>Prediction: {{ result.label }} ({{ result.confidence }}% confident)</p>`<br> })<br> export class ResultDisplayComponent {<br> result = { label: '', confidence: 0 };<br> constructor(private http: HttpClient) {<br> this.fetchResult();<br> }<br> fetchResult() {<br> this.http.get<any>('https://api.example.com/model-result')<br> .subscribe(res => this.result = res);<br> }<br> }<br>
Offline AI Processing in Angular
-
Offline AI allows predictions using pre-trained models embedded in the browser (e.g., with TensorFlow.js), eliminating the need for API calls.
Example: Use TensorFlow.js to Predict Offline
import * as tf from '@tensorflow/tfjs';<br> // Load a pre-trained model from local or remote<br> tf.loadLayersModel('assets/model.json').then(model => {<br> const input = tf.tensor2d([[5.1, 3.5, 1.4, 0.2]]); // Iris data<br> const prediction = model.predict(input) as tf.Tensor;<br> prediction.print(); // Output prediction in console<br> });<br>
Using WebAssembly (WASM) for AI Tasks
Explanation:
WebAssembly allows running AI models efficiently at near-native speed in the browser.
Example: Load WASM Module for Inference
// Load a WASM-compiled AI model (e.g., ONNX Runtime Web)<br> import { InferenceSession } from 'onnxruntime-web';<br> async function runWasmModel() {<br> const session = await InferenceSession.create('assets/model.onnx');<br> const inputTensor = new ort.Tensor('float32', new Float32Array([1.0, 2.0]), [1, 2]);<br> const feeds = { input: inputTensor };<br> const results = await session.run(feeds);<br> console.log('WASM Result:', results.output.data);<br> }<br> runWasmModel();<br>
Angular + AI for Educational Apps
Explanation:
Use AI to generate quizzes, check answers, provide feedback, and personalize learning experiences.
Example: AI-Generated Quiz Questions
const topic = 'Photosynthesis';<br> fetch('https://api.education-ai.com/generate-quiz', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ topic })<br> })<br> .then(res => res.json())<br> .then(data => console.log('Generated Quiz:', data));<br>
Creating Voice Assistants in Angular
Explanation:
Voice assistants can use speech recognition and synthesis to create interactive voice-based UIs.
Example: Simple Voice Assistant in Angular
const recognition = new (window as any).webkitSpeechRecognition();<br> recognition.onresult = (event: any) => {<br> const voiceInput = event.results[0][0].transcript;<br> console.log('User said:', voiceInput);<br> const response = new SpeechSynthesisUtterance(`You said: ${voiceInput}`);<br> speechSynthesis.speak(response);<br> };<br> recognition.start();<br>
Interactive AI Forms with Smart Validation
Explanation:
AI can help users fill forms faster and validate fields based on natural language or logic patterns.
Example: AI Suggests Job Titles
const input = 'software...';<br> fetch('https://api.smartform.ai/suggestions', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ field: 'jobTitle', partial: input })<br> })<br> .then(res => res.json())<br> .then(data => console.log('Suggested Titles:', data));<br>
Embedding Custom AI Services into Angular
Explanation:
Integrate your own trained models or APIs by building endpoints and calling them from Angular.
Example: Call Custom Sentiment API
const text = 'I love Angular!';<br> fetch('https://yourdomain.com/api/sentiment', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ text })<br> })<br> .then(res => res.json())<br> .then(result => console.log('Sentiment:', result));<br>
Custom AI Model Deployment with Angular Frontend
Explanation:
You can deploy models (e.g., Flask + TensorFlow) on the backend and connect them via Angular for real-time predictions.
Example: Angular Sends Features to Python Model
const data = { feature1: 0.5, feature2: 0.8 };<br> fetch('http://localhost:5000/predict', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify(data)<br> })<br> .then(res => res.json())<br> .then(prediction => console.log('Model Output:', prediction));<br>
Using Angular to Monitor AI Metrics
Explanation:
Angular can display real-time metrics such as loss, accuracy, or model confidence using charts.
Example: Display Training Accuracy with Chart.js
// In component
data = { labels: ['Epoch 1', '2', '3'], datasets: [{ label: 'Accuracy', data: [0.8, 0.85, 0.9] }] };
// In template
<canvas baseChart
[data]="data"
[type]="'line'"></canvas>
Model Explainability in Angular (SHAP/LIME)
Explanation:
Use explainable AI (XAI) techniques to show which features influenced a model’s decision.
Example: Show SHAP-like Explanation from API
fetch('https://api.explainable-ai.com/explain', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: [0.2, 0.5] })
})
.then(res => res.json())
.then(data => console.log('Feature Importance:', data));
Testing and Validating AI Integrations
Explanation:
It’s important to test AI outputs for correctness, latency, and robustness.
Example: Simple Test Case in Angular
// Jasmine test to validate AI response shape<br> it('should return a valid AI result', (done) => {<br> fetch('https://api.example.com/analyze', {<br> method: 'POST',<br> headers: { 'Content-Type': 'application/json' },<br> body: JSON.stringify({ input: 'test' })<br> })<br> .then(res => res.json())<br> .then(result => {<br> expect(result).toHaveProperty('score');<br> expect(typeof result.score).toBe('number');<br> done();<br> });<br> });<br>