Angular


Beginners To Experts


The site is under development.

Angular Tutorial

What is Angular?

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
}
      

History and Evolution of Angular

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 {}
      

Angular vs AngularJS

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 vs React vs Vue

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>
      

Prerequisites and Tools

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
      

Installing Angular 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
      

Creating Your First Angular App

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
      

Project Structure Overview

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
      

Introduction to TypeScript

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
      

Data Types and Interfaces

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
      

Classes and Objects

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 and Namespaces

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
      

Functions and Arrow Functions

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 and Enums

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
      

TypeScript Compiler Options

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
  }
}
      

TypeScript with Angular

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
}
      

What is a Component?

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
}
      

Component Decorator Explained

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
}
      

Template and Styles

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
}
      

Component Lifecycle Hooks

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

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 {}
      

Communication with @Input

@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
}
      

Communication with @Output

@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
  }
}
      

Component Best Practices

Follow these tips:

  • Keep components small and focused.
  • Use @Input and @Output for communication.
  • Use external files for templates and styles.

// 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
}
      

Template Syntax

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

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 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 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

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 -->
      

Template Reference Variables

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 -->
      

ngModel Directive

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 and Pipes

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 -->
      

What are Directives?

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
      

Built-in Structural Directives

Structural directives modify the layout of the DOM. Common ones include *ngIf, *ngFor, and *ngSwitch.

*ngIf

<div *ngIf="isVisible"> // Only show if isVisible is true
  <p>This is conditionally visible.</p>
</div>
      

*ngFor

<ul>
  <li *ngFor="let item of items"> // Loop through 'items' array
    {{ item }} // Display each item
  </li>
</ul>
      

*ngSwitch

<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

Attribute directives change the appearance or behavior of an element. Common ones include ngClass and ngStyle.

ngClass

<div [ngClass]="{ 'active': isActive }"> // Apply 'active' class if isActive is true
  This box uses ngClass
</div>
      

ngStyle

<div [ngStyle]="{ 'color': isRed ? 'red' : 'black' }"> // Change color based on isRed
  Text styled with ngStyle
</div>
      

Custom Attribute Directives

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
      

Custom Structural Directives

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>
      

HostBinding and HostListener

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>
      

What are Services?

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
  }
}
      

Creating a Service

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
  }
}
      

Using Dependency Injection

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
  }
}
      

Singleton Services

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
      

@Injectable Decorator

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
  }
}
      

Hierarchical Injectors

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
  }
}
      

Service Lifecycle

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
      

Best Practices for Services

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
  }
}
      

Setting up Routing

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 and Routes

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
];
      

Navigating with RouterLink

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>
      

Route Parameters

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
    });
  }
}
      

Nested Routes (Child Routes)

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 and Wildcards

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
      

Lazy Loading Modules

Modules can be loaded on demand to optimize app performance.

const routes: Routes = [
  { path: 'shop', loadChildren: () => import('./shop/shop.module').then(m => m.ShopModule) }
];
      

Route Guards (AuthGuard, etc.)

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

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

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 and FormControl

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 and Custom Validators

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

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
  }
}
      

Handling Form Events

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

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
  }
}
      

Form Error Display

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>
      

Introduction to Pipes

Pipes transform displayed data in templates, formatting values easily.

Example: Using built-in uppercase pipe

<!-- 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 -->
      

Built-in Pipes (Date, Currency, etc.)

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

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 vs Impure Pipes

Pure pipes execute only when input changes; impure pipes run on every change detection cycle.

Declaring an impure pipe:

@Pipe({
  name: 'impureExample',
  pure: false // Mark pipe as impure
})
      

Pipe Parameters

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>
      

Chaining Pipes

You can chain multiple pipes for combined transformations.

<p>{{ title | lowercase | slice:0:7 | uppercase }}</p> <!-- Converts to lowercase, slices substring, then uppercase -->
      

Async Pipe

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 -->
      

Best Practices with Pipes

  • Use pure pipes whenever possible for performance.
  • Avoid complex logic in pipes; keep them simple.
  • Use async pipes to handle observable subscriptions cleanly.
  • Test custom pipes thoroughly.

Angular HttpClientModule

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 { }
      

Sending GET Requests

// 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
  }
}
      

Sending POST, PUT, DELETE

// 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
}
      

Handling Errors

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
    })
  );
}
      

Using Observables with HTTP

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

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
  }
}
      

Headers and Query Params

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
});
      

Connecting to REST APIs

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
  }
}
      

What is an Angular Module?

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 Metadata

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 vs Feature Modules

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

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 Loaded Modules

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 and SharedModule

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 vs Imports

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 { }
      

Best Practices for Modules

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 { }
      

Introduction to RxJS

RxJS is a reactive programming library that allows handling asynchronous data streams using Observables.

What are 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
});
      

Subscribing and Unsubscribing

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 (map, filter, etc.)

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 and BehaviorSubject

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
      

Combining Observables

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
});
      

Error Handling with Observables

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
      

Async Programming Best Practices

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>
      

Why Use Animations?

Animations improve user experience by adding smooth transitions and feedback on UI interactions.

Animation Triggers

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 and Transitions

States define styles, transitions define animations between states.

Animate Styles

Use style() inside animate() to animate CSS properties.

transition('void => *', [
  style({ opacity: 0 }),
  animate(500, style({ opacity: 1 })) // Fade in animation
])
      

Keyframes

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 and Sequence

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 }))
    ])
  ])
])
      

Animation Callbacks

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!');
}
      

Reusable Animation Functions

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' } })
      ])
    ])
  ]
})
      

Introduction to Testing

Testing ensures application reliability and catches bugs early.

Jasmine and Karma

Jasmine is a testing framework; Karma runs tests in browsers.

Example: Simple Jasmine test

// 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
  });
});
      

Unit Testing Components

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();
  });
});
      

Unit Testing Services

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');
  });
});
      

HTTP Testing

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();
});
      

Testing Directives and Pipes

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!');
  });
});
      

End-to-End Testing with Protractor

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
  }
};
      

Best Practices for Testing

  • Write clear and isolated tests.
  • Mock dependencies and HTTP calls.
  • Use async and fakeAsync for async code.
  • Run tests regularly and automate with CI/CD.

Introduction to Angular Material

Angular Material provides reusable UI components based on Google's Material Design for Angular apps.

Installing Material Components

// Run Angular CLI command to install Angular Material
ng add @angular/material
// This installs packages and updates your app module with Material imports automatically
      

Navigation and Layout

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>
      

Buttons and Indicators

// Using Material buttons and progress spinner
<button mat-raised-button color="accent">Click Me</button>

<mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
      

Form Controls

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>
      

Data Table and Pagination

// 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>
      

Dialogs and Modals

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
}
      

Theming and Customization

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);
      

Introduction to State Management

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 Basics

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, Reducers, Effects

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) {}
}
      

Store Selectors

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)
);
      

Using NgRx with Components

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
  }
}
      

DevTools for NgRx

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 { }
      

Advanced NgRx Patterns

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());
  }
}
      

NgRx Best Practices

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 Strategies

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 and Logout Flow

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
}
      

JWT Token Handling

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);
  }
});
      

Route Guards for Auth

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;
  }
}
      

Storing Auth State

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');
      

Role-Based Access

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
}
      

Interceptor for Token Injection

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 & Social Login Integration

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
      

File Upload with HttpClient

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
  });
}
      

Progress Indicators

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');
  }
});
      

Drag-and-Drop File Upload

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);
  }
}
      

File Type Restrictions

Restrict accepted file types for upload.

<input type="file" accept=".png,.jpg,.jpeg" (change)="onFileSelected($event)" />
      

File Downloads

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
});
      

Blob Handling

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 to Firebase

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');
});
      

Best Practices for File Handling

  • Validate files client-side before upload
  • Limit file size
  • Sanitize filenames
  • Handle errors gracefully
  • Secure file storage and access

What is i18n?

Internationalization (i18n) is the process of designing your app to support multiple languages and regions.

Angular i18n Setup

Angular provides built-in i18n support for translating templates and managing locales.

Example: Adding i18n attribute in template

<h1 i18n>Welcome to our Application!</h1>  
      

Translating Templates

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>
      

Locale Management

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');
      

Date and Currency Localization

Angular pipes automatically adapt date and currency formatting based on locale.

<p>{{ today | date:'fullDate' }}</p>  
<p>{{ price | currency:'EUR' }}</p>   
      

Dynamic Translations

For runtime translation changes, use libraries like ngx-translate.

Example: ngx-translate usage

// 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>  
      

Best Practices in i18n

  • Mark all user-facing text for translation.
  • Use translation files and avoid hardcoded strings.
  • Test your app in all supported locales.
  • Handle pluralization and gender correctly.
  • Consider right-to-left language support.

Change Detection Strategy

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 Strategy

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
}
      

Lazy Loading Optimization

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
  }
];
      

Bundle Analyzer

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
      

Tree Shaking

Remove unused code from bundles automatically during build.

// Angular CLI uses Webpack tree shaking by default on production builds
ng build --prod
      

Ahead-of-Time Compilation

Compile templates during build instead of runtime for faster startup.

// Enable AOT compilation in Angular CLI
ng build --prod --aot
      

Caching and Service Workers

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
      

Code Splitting

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)
      

What is a PWA?

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.

Setting up Angular PWA

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 Worker Basics

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"
      

App Manifest Configuration

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"
    }
  ]
}
      

Caching Strategies

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/**"
        ]
      }
    }
  ]
}
      

Offline Mode

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

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));
}
      

Deploying a PWA

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 Overview

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 Setup

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 {}
      

Real-time Database Integration

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 with Angular

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();
}
      

Firebase Authentication

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();
}
      

Firebase Storage

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);
}
      

Hosting Angular Apps

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
      

Security Rules and Monitoring

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;
    }
  }
}
      

Dynamic Component Loading

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
}
      

Content Projection

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>
      

Custom Decorators

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);
}
      

ElementRef and Renderer2

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
}
      

ChangeDetectorRef

Manually control change detection in components.

constructor(private cd: ChangeDetectorRef) {}

someMethod() {
  // Update data then detect changes manually
  this.data = 'new value';
  this.cd.detectChanges();
}
      

Working with Web Workers

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');
}
      

SSR and Angular Universal

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
      

Micro Frontends

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'],
    }),
  ],
};
      

Building Angular App

Use Angular CLI to build your project for production.

// Command to build Angular app for production optimization
ng build --prod
      

Environment Configuration

Angular supports multiple environment files for different setups.

// src/environments/environment.prod.ts
export const environment = {
  production: true,
  apiUrl: 'https://api.production.com'
};
      

Deploying on Firebase

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
      

Deploying on Netlify/Vercel

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.
      

CI/CD with GitHub Actions

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 }}
      

Dockerizing Angular App

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;"]
      

Monitoring & Error Logging

Use tools like Sentry or LogRocket for tracking runtime errors and performance.

Version Control Integration

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
      

E-commerce Web App

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>';
}
?>
      

Social Media Dashboard

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>';
?>
      

Real-Time Chat App

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>
      

Task Management Tool

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>
      

Weather Forecast App

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>';
?>
      

Job Listing Portal

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>';
}
?>
      

Online Portfolio Website

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>';
}
?>
      

Final Project Presentation

Prepare a presentation highlighting your final capstone project achievements.

No code example needed here.

1. Introduction to AI Integration in Angular

Angular apps can be enhanced by integrating AI technologies to provide smarter, more interactive experiences.

2. Overview of AI Technologies

AI technologies include machine learning, NLP, computer vision, and more.

3. Why Integrate AI with Angular?

AI integration enables powerful features like chatbots, recommendations, and predictive analytics within Angular apps.

4. Setting up Angular for AI Projects

// 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
      

5. Working with RESTful AI APIs

Use Angular HttpClient to connect to AI APIs providing RESTful endpoints.

6. Calling AI APIs with Angular HttpClient

<!-- 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 });
  }
}
      

7. Authentication for AI Services (API Keys, OAuth)

Secure your API calls using keys or OAuth tokens.

8. Using OpenAI API with Angular

// 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);
});
      

9. Integrating Google Cloud AI Services

Google Cloud offers Vision API, NLP API, and more accessible via REST and client libraries.

10. Using Microsoft Azure Cognitive Services

Azure provides AI APIs like Text Analytics, Computer Vision, and Speech Services.

11. IBM Watson Integration Basics

IBM Watson offers various AI services like conversation, language translation, and visual recognition.

12. Chatbots in Angular: Overview

Build interactive AI chatbots using Angular components and AI backends.

13. Building a Simple AI Chatbot UI

<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 = '';
}
      

14. Connecting Angular to Dialogflow

Use Dialogflow's REST API or SDK to integrate conversational AI in Angular.

15. Natural Language Processing (NLP) APIs Integration

Integrate NLP APIs for text analysis, entity recognition, sentiment analysis, etc.

16. Sentiment Analysis with AI APIs

Call AI sentiment APIs to analyze user input and display feedback.

17. Image Recognition and AI APIs

Use APIs like Google Vision or Azure Computer Vision for image classification in Angular apps.

18. Integrating TensorFlow.js with Angular

// 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);
}
      

19. Running Pretrained Models in Angular

Leverage TensorFlow.js or ONNX.js to run models directly in the browser.

20. Custom AI Model Hosting and Access

Host AI models on cloud or servers and access via REST APIs from Angular.

21. Using WebSockets for Real-Time AI Data

Use WebSockets for live AI data streams like chat or predictions.

22. AI-Powered Recommendations in Angular

Integrate recommendation engines to personalize user experience.

23. Voice Recognition Integration

Use Web Speech API or cloud services for voice input processing.

24. Text-to-Speech in Angular Apps

Implement speech synthesis to read content aloud.

25. Speech-to-Text Integration

Convert spoken words into text for commands or input fields.

26. Facial Recognition Integration

Use AI APIs or TensorFlow.js for facial recognition features.

27. Angular with AI for Predictive Analytics

Analyze data patterns to forecast future trends within Angular apps.

28. Integrating AI for User Behavior Analytics

Use AI to understand and optimize user interaction.

29. AI for Personalization in Angular Apps

Deliver personalized content using AI-driven insights.

30. AI-Powered Search Implementation

Enhance search capabilities with AI-powered ranking and filtering.

31. AI-Powered Image/Video Processing

Implement real-time AI-based processing for media files.

32. Data Preprocessing for AI in Angular

Prepare and clean data for AI workflows.

33. Integrating AI for Fraud Detection

Detect fraudulent activity by analyzing behavioral patterns.

34. AI in Angular for Medical Applications

Use AI for diagnostics, patient monitoring, and more.

35. AI for Real-Time Translation

Enable live language translation features.

36. AI-Powered Accessibility Features

Improve app accessibility with AI tools like speech-to-text and image description.

37. Building AI-Driven Dashboards

Create dashboards that visualize AI insights in real time.

38. AI Chatbots with Context Awareness

Build chatbots that understand conversation context for better interactions.

39. Training and Updating AI Models via Angular

Implement UI for retraining or updating AI models dynamically.

40. Handling AI Model Results and Visualization

Display AI predictions and insights using charts and graphs.

41. Integrating AI with Angular Forms

Use AI to validate, auto-fill, or suggest input in forms.

42. AI for Automated Testing of Angular Apps

Leverage AI tools to improve testing coverage and efficiency.

43. Using AI to Optimize Angular Performance

Apply AI to monitor and enhance app performance.

44. AI and Angular Security Enhancements

Use AI for threat detection and enhanced security features.

45. Ethical Considerations in AI Integration

Address privacy, bias, and fairness when integrating AI.

46. Cost Management of AI Services

Monitor usage and control costs of AI API calls.

47. Monitoring AI API Usage in Angular Apps

Track API performance and errors to ensure reliability.

48. Debugging AI Integrations in Angular

Strategies for troubleshooting AI-related issues.

49. Future Trends: AI and Angular Ecosystem

Explore upcoming innovations combining AI and Angular.

50. Final Project: Building a Full AI-Integrated Angular Application

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>