Python Java C++ HTML CSS Bootstrap JavaScript jQuery AngularJS React Node.js TypeScript Django NumPy Pandas Matplotlib Seaborn Machine Learning Deep Learning Decipher XML

Introduction

Angular is a full-featured front-end platform for building large, maintainable single-page applications. It uses TypeScript, a strict component model, and a powerful compiler to turn templates into efficient JavaScript.

Core ideas include:

  • Component-driven UI: each feature is isolated with its own template, logic, and styles
  • Declarative templates: bindings, directives, and pipes keep UI in sync with data
  • Dependency injection: services are shared cleanly across the app
  • Reactive programming: RxJS streams handle async data, events, and state
Angular includes routing, forms, HTTP, testing utilities, and a CLI so teams can standardize structure and scale reliably.

Setup & Installation

# Install Node.js & npm
# Install Angular CLI globally
npm install -g @angular/cli

# Create a new project
ng new my-app
cd my-app
ng serve --open

Angular CLI creates a workspace with a build system, TypeScript config, linting, testing, and environment files. It also supports code generation for components, services, and modules.

Advanced setup tips:

  • Use ng new --routing --style=scss to enable routing and SCSS at creation
  • Configure file replacements for environment-specific builds
  • Use ng build --configuration=production for optimized output
# Generate a component and service
ng g c features/profile
ng g s services/auth

# Build with production optimizations
ng build --configuration=production

Components

// app.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `

`, }) export class AppComponent { title = 'Hello Angular'; }

Components encapsulate UI, behavior, and styling. The Angular compiler links templates to component classes and tracks updates using change detection.

Key component concepts:

  • Inputs and outputs for parent-child communication
  • Template and style encapsulation by default
  • Lifecycle hooks to manage setup and teardown
@Component({
  selector: 'app-card',
  template: `
    

` }) export class CardComponent { @Input() title = ''; @Input() id = 0; @Output() select = new EventEmitter(); }

Modules

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

Modules group related functionality and control compilation scope. Feature modules keep apps organized and can be lazy‑loaded for performance.

Best practices:

  • Keep shared UI in a SharedModule (components, pipes)
  • Use feature modules for domains like OrdersModule
  • Lazy‑load large sections with the router
@NgModule({
  declarations: [ProfileComponent],
  imports: [CommonModule, ProfileRoutingModule]
})
export class ProfileModule {}

Directives

// Structural
<div *ngIf="isVisible">Visible</div>

// Attribute
<div [class.active]="isActive">Dynamic Class</div>

Directives extend HTML with custom behavior. Structural directives change layout by adding or removing elements, while attribute directives modify element appearance or behavior.

Common structural directives:

  • *ngIf, *ngFor, *ngSwitch
  • ng-container for grouping without extra DOM nodes
<ul>
  <li *ngFor="let item of items; trackBy: trackById"></li>
</ul>

Data Binding

// Interpolation
<h1></h1>
// Property binding
<img [src]="imageUrl">
// Event binding
<button (click)="doSomething()">Click</button>

Angular supports one‑way data flow and optional two‑way binding. Templates stay in sync with component state through bindings evaluated in change detection cycles.

Advanced binding patterns:

  • Two‑way binding via [(ngModel)] or custom @Input/@Output
  • Property binding for attributes and DOM properties (e.g., [disabled])
  • Event binding with arguments and $event
<input [value]="name" (input)="name = $event.target.value">
<app-toggle [(state)]="isOn"></app-toggle>

Services & Dependency Injection

import { Injectable } from '@angular/core';
@Injectable({providedIn:'root'})
export class DataService {
  getData(){ return ['A','B','C']; }
}
constructor(private dataService: DataService){}
ngOnInit(){ console.log(this.dataService.getData()); }

Services hold shared logic and state. Angular's DI container manages lifecycles and allows easy mocking in tests.

Key DI concepts:

  • Singleton services via providedIn: 'root'
  • Scoped providers in feature modules or components
  • Injection tokens for non-class dependencies
export const API_URL = new InjectionToken('apiUrl');

@NgModule({
  providers: [{ provide: API_URL, useValue: '/api' }]
})
export class CoreModule {}

Routing

import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];
@NgModule({imports:[RouterModule.forRoot(routes)],exports:[RouterModule]})

The Angular Router maps URLs to components. It supports guards, lazy loading, parameters, and nested routes for complex layouts.

Common routing features:

  • Route params with /users/:id
  • Route guards for auth and permissions
  • Lazy loading with loadChildren
const routes: Routes = [
  { path: 'users/:id', component: UserComponent, canActivate: [AuthGuard] },
  { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
];

Forms

// Template-driven
<form #myForm="ngForm">
  <input name="name" [(ngModel)]="name">
</form>

// Reactive
this.form = this.fb.group({name:['']});

Template-driven forms are simple and declarative, while reactive forms scale better for complex validation, dynamic fields, and testability.

Reactive form advantages:

  • Fine-grained validation and custom validators
  • Explicit form state in code
  • Reactive value changes via observables
this.form = this.fb.group({
  name: ['', [Validators.required, Validators.minLength(3)]],
  email: ['', [Validators.required, Validators.email]]
});

this.form.valueChanges.subscribe(value => console.log(value));

HTTP Client

import { HttpClient } from '@angular/common/http';
this.http.get('https://api.example.com/data')
  .subscribe(data => console.log(data));

HttpClient returns observables and integrates with RxJS operators. It supports typed responses, interceptors, and error handling.

Advanced usage:

  • Interceptors for auth tokens, logging, or retries
  • Typed responses for compile-time safety
  • Centralized error handling with catchError
this.http.get('/api/users')
  .pipe(catchError(err => of([])))
  .subscribe(users => this.users = users);

Pipes

{ today | date:'fullDate' }
{ amount | currency:'USD' }

Pipes transform values for display. Angular provides built‑in pipes for dates, numbers, JSON, and strings, and you can create custom pipes.

Custom pipes should be pure by default for performance.

@Pipe({ name: 'truncate' })
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 20): string {
    return value.length > limit ? value.slice(0, limit) + '...' : value;
  }
}

Component Lifecycle

ngOnInit() {}
ngOnChanges(changes) {}
ngOnDestroy() {}

Lifecycle hooks let you tap into component creation, updates, and destruction. This is essential for subscriptions, timers, and DOM interactions.

Common hooks:

  • ngOnInit for initialization
  • ngOnChanges to react to input changes
  • ngOnDestroy for cleanup
private sub?: Subscription;

ngOnInit() {
  this.sub = this.service.stream$.subscribe();
}

ngOnDestroy() {
  this.sub?.unsubscribe();
}

Observables & RxJS

import { of } from 'rxjs';
of(1,2,3).subscribe(x => console.log(x));

Observables represent asynchronous streams that can emit multiple values over time. RxJS provides operators to transform, filter, and combine streams.

Key operators:

  • map, filter, switchMap
  • debounceTime for input handling
  • catchError for graceful failures
this.searchControl.valueChanges.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(term => this.http.get(`/api/search?q=${term}`))
).subscribe(results => this.results = results);