Angular coding QA

Angular Coding Exercises

1️⃣ Create a Component Using Angular CLI

ng generate component user

2️⃣ Write a Simple Angular Component

import { Component } from '@angular/core';

@Component({
  selector: 'app-test',
  template: '<h1>Hello Angular</h1>'
})
export class TestComponent {}

3️⃣ Syntax for ngFor

<li *ngFor="let item of items">{{ item }}</li>

4️⃣ Create a Custom Pipe to Reverse a String

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
  transform(value: string): string {
    return value.split('').reverse().join('');
  }
}

// Usage in template
<p>{{ 'Angular' | reverse }}</p>  <!-- Output: ralugnA -->

5️⃣ Subscribe to an Observable Using AsyncPipe

<p>{{ data$ | async }}</p>

Explanation: Using AsyncPipe automatically subscribes to an Observable and displays the latest value. It also handles unsubscription when the component is destroyed.

Angular Practical Examples

1️⃣ Create a Service using Angular CLI

ng generate service services/user

2️⃣ Create a Directive using Angular CLI

ng generate directive directives/highlight

3️⃣ Create a Pipe using Angular CLI

ng generate pipe pipes/capitalize

4️⃣ Property Binding Example

<img [src]="imageUrl" />

imageUrl = 'assets/logo.png';

5️⃣ Event Binding Example

<button (click)="sayHello()">Click</button>

sayHello() {
  alert("Hello Angular!");
}

6️⃣ Two-way Binding Example

<input [(ngModel)]="name" />
<p>{{ name }}</p>

name = '';

7️⃣ Custom Directive: Highlight on Hover

import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private el: ElementRef, private renderer: Renderer2) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor');
  }
}
Usage:
<p appHighlight>Hover me</p>

8️⃣ Custom Pipe: Capitalize First Letter

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'capitalize' })
export class CapitalizePipe implements PipeTransform {
  transform(value: string): string {
    if (!value) return '';
    return value.charAt(0).toUpperCase() + value.slice(1);
  }
}
Usage:
<p>{{ 'angular' | capitalize }}</p>

9️⃣ Create an Interface and Use it in an Array

export interface User {
  id: number;
  name: string;
  email: string;
}

users: User[] = [
  { id: 1, name: 'Sai', email: 'sai@gmail.com' },
  { id: 2, name: 'Balaji', email: 'balaji@gmail.com' }
];

🔟 Use ngIf with else

<div *ngIf="isLoggedIn; else loginBlock">
  Welcome User!
</div>

<ng-template #loginBlock>
  Please login
</ng-template>

1️⃣1️⃣ Create a Reactive Form (Basic)

// component.ts
import { FormControl, FormGroup, Validators } from '@angular/forms';

form = new FormGroup({
  name: new FormControl('', Validators.required),
  email: new FormControl('', [Validators.required, Validators.email])
});

submit() {
  console.log(this.form.value);
}

// component.html
<form [formGroup]="form" (ngSubmit)="submit()">
  <input formControlName="name" placeholder="Name" />
  <input formControlName="email" placeholder="Email" />
  <button type="submit">Submit</button>
</form>

1️⃣2️⃣ Call API using HttpClient (GET)

// service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class UserService {
  constructor(private http: HttpClient) {}

  getUsers(): Observable<any[]> {
    return this.http.get<any[]>('https://jsonplaceholder.typicode.com/users');
  }
}

// component.ts
users: any[] = [];

constructor(private userService: UserService) {}

ngOnInit() {
  this.userService.getUsers().subscribe(res => {
    this.users = res;
  });
}

1️⃣3️⃣ Async Pipe with HttpClient

users$ = this.userService.getUsers();

<li *ngFor="let user of users$ | async">
  {{ user.name }}
</li>

1️⃣4️⃣ Create a Route (Routing Module)

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'users', component: UsersComponent }
];

1️⃣5️⃣ Navigation using RouterLink

<a routerLink="/users">Users</a>

1️⃣6️⃣ Route Parameter Example

// route
{ path: 'user/:id', component: UserDetailsComponent }

// reading param
constructor(private route: ActivatedRoute) {}

ngOnInit() {
  const id = this.route.snapshot.paramMap.get('id');
  console.log(id);
}

✅ Advanced Angular Coding Exercises (Angular 17+)

1️⃣ Create a Standalone Component

ng generate component dashboard --standalone

import { Component } from '@angular/core';

@Component({
  selector: 'app-dashboard',
  standalone: true,
  template: `<h2>Dashboard Works!</h2>`
})
export class DashboardComponent {}

2️⃣ Create a Route Guard (AuthGuard)

ng generate guard guards/auth

import { CanActivateFn, Router } from '@angular/router';
import { inject } from '@angular/core';

export const authGuard: CanActivateFn = () => {
  const router = inject(Router);
  const token = localStorage.getItem('token');
  if (!token) {
    router.navigate(['/login']);
    return false;
  }
  return true;
};
Usage:
{ path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] }

3️⃣ Create an HTTP Interceptor (JWT Token)

ng generate interceptor interceptors/auth

import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = localStorage.getItem('token');
  if (token) {
    req = req.clone({
      setHeaders: { Authorization: `Bearer ${token}` }
    });
  }
  return next(req);
};
Register in app.config.ts:
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './interceptors/auth.interceptor';

export const appConfig = {
  providers: [provideHttpClient(withInterceptors([authInterceptor]))]
};

4️⃣ Handle HTTP Error using catchError

import { catchError, throwError } from 'rxjs';

getUsers() {
  return this.http.get<any[]>('/api/users').pipe(
    catchError(err => {
      console.error("API Error:", err);
      return throwError(() => err);
    })
  );
}

5️⃣ BehaviorSubject Login State (AuthService)

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private isLoggedInSubject = new BehaviorSubject<boolean>(false);
  isLoggedIn$ = this.isLoggedInSubject.asObservable();

  login(token: string) {
    localStorage.setItem('token', token);
    this.isLoggedInSubject.next(true);
  }

  logout() {
    localStorage.removeItem('token');
    this.isLoggedInSubject.next(false);
  }
}

6️⃣ Debounce Search using RxJS

import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs';
import { UserService } from './user.service';

searchControl = new FormControl('');

users$ = this.searchControl.valueChanges.pipe(
  debounceTime(500),
  distinctUntilChanged(),
  switchMap(value => this.userService.searchUsers(value || ''))
);

constructor(private userService: UserService) {}
HTML:
<input [formControl]="searchControl" placeholder="Search users..." />
<ul>
  <li *ngFor="let user of users$ | async">{{ user.name }}</li>
</ul>

7️⃣ Lazy Loading Module

ng generate module admin --route admin --module app.module

{
  path: 'admin',
  loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}

8️⃣ Route Resolver (Load Data Before Page Loads)

import { ResolveFn } from '@angular/router';
import { inject } from '@angular/core';
import { UserService } from './user.service';

export const userResolver: ResolveFn<any> = (route) => {
  const userService = inject(UserService);
  const id = route.paramMap.get('id')!;
  return userService.getUserById(id);
};
Route usage:
{ path: 'user/:id', component: UserDetailsComponent, resolve: { user: userResolver } }
Component:
constructor(private route: ActivatedRoute) {}

ngOnInit() {
  const user = this.route.snapshot.data['user'];
  console.log(user);
}

9️⃣ TrackBy with ngFor (Performance Optimization)

<li *ngFor="let user of users; trackBy: trackById">{{ user.name }}</li>

trackById(index: number, user: any) {
  return user.id;
}

1️⃣0️⃣ ChangeDetectionStrategy.OnPush

import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-card',
  template: `<p>{{ user.name }}</p>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserCardComponent {
  @Input() user: any;
}

1️⃣1️⃣ Signals (Angular 17+)

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
    <h2>{{ count() }}</h2>
    <button (click)="increment()">+</button>
  `
})
export class CounterComponent {
  count = signal(0);

  increment() {
    this.count.update(v => v + 1);
  }
}

1️⃣2️⃣ Signal + Computed Example

import { Component, signal, computed } from '@angular/core';

@Component({
  selector: 'app-total',
  template: `
    <p>Price: {{ price() }}</p>
    <p>Qty: {{ qty() }}</p>
    <p>Total: {{ total() }}</p>
  `
})
export class TotalComponent {
  price = signal(100);
  qty = signal(2);

  total = computed(() => this.price() * this.qty());
}

1️⃣3️⃣ Dynamic FormArray

import { FormArray, FormBuilder, Validators } from '@angular/forms';

constructor(private fb: FormBuilder) {}

form = this.fb.group({
  items: this.fb.array([])
});

get items() {
  return this.form.get('items') as FormArray;
}

addItem() {
  this.items.push(
    this.fb.group({
      name: ['', Validators.required],
      qty: [1, Validators.required]
    })
  );
}
HTML:
<div formArrayName="items">
  <div *ngFor="let item of items.controls; let i=index" [formGroupName]="i">
    <input formControlName="name" placeholder="Item Name" />
    <input formControlName="qty" type="number" />
  </div>
</div>

<button (click)="addItem()">Add Item</button>

1️⃣4️⃣ Custom Validator (Password Match)

import { AbstractControl, ValidationErrors } from '@angular/forms';

export function passwordMatchValidator(control: AbstractControl): ValidationErrors | null {
  const password = control.get('password')?.value;
  const confirm = control.get('confirmPassword')?.value;

  if (password !== confirm) {
    return { passwordMismatch: true };
  }
  return null;
}

form = new FormGroup(
  {
    password: new FormControl(''),
    confirmPassword: new FormControl('')
  },
  { validators: passwordMatchValidator }
);

✅ SUPER ADVANCED Angular Coding Exercises (ALL)


1) NgRx Store (Mini Example: Actions → Reducer → Selector)

Install:

ng add @ngrx/store

counter.actions.ts

import { createAction } from '@ngrx/store';

export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');
export const reset = createAction('[Counter] Reset');

counter.reducer.ts

import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';

export const initialState = 0;

export const counterReducer = createReducer(
  initialState,
  on(increment, state => state + 1),
  on(decrement, state => state - 1),
  on(reset, () => 0)
);

app.module.ts

import { StoreModule } from '@ngrx/store';
import { counterReducer } from './store/counter.reducer';

@NgModule({
  imports: [
    StoreModule.forRoot({ count: counterReducer })
  ]
})
export class AppModule {}

counter.component.ts

import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { increment, decrement, reset } from './store/counter.actions';

@Component({
  selector: 'app-counter',
  template: `
    

{{ count$ | async }}

` }) export class CounterComponent { count$ = this.store.select(state => state.count); constructor(private store: Store<{ count: number }>) {} inc() { this.store.dispatch(increment()); } dec() { this.store.dispatch(decrement()); } res() { this.store.dispatch(reset()); } }

2) SSR (Angular Universal) Setup

ng add @nguniversal/express-engine
✅ Use case:
• SEO friendly
• Faster first load
• Better performance for public websites

3) PWA Setup

ng add @angular/pwa
✅ Adds:
• Service worker
• Offline caching
• Installable web app

4) Unit Testing (Jasmine + Karma) Component Test

component.ts

@Component({
  selector: 'app-test',
  template: `

{{ title }}

` }) export class TestComponent { title = 'Angular Testing'; }

component.spec.ts

import { TestBed } from '@angular/core/testing';
import { TestComponent } from './test.component';

describe('TestComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestComponent]
    });
  });

  it('should create component', () => {
    const fixture = TestBed.createComponent(TestComponent);
    const comp = fixture.componentInstance;
    expect(comp).toBeTruthy();
  });

  it('should have correct title', () => {
    const fixture = TestBed.createComponent(TestComponent);
    expect(fixture.componentInstance.title).toBe('Angular Testing');
  });
});

5) WebSocket Real-time Example (Observable)

web-socket.service.ts

import { Injectable } from '@angular/core';
import { webSocket } from 'rxjs/webSocket';

@Injectable({ providedIn: 'root' })
export class WebSocketService {
  private socket$ = webSocket('ws://localhost:8080');

  sendMessage(msg: string) {
    this.socket$.next(msg);
  }

  getMessages() {
    return this.socket$;
  }
}

component.ts

messages: string[] = [];

ngOnInit() {
  this.ws.getMessages().subscribe(msg => {
    this.messages.push(msg as string);
  });
}

6) ViewChild Example (Access Child Component)

child.component.ts

@Component({
  selector: 'app-child',
  template: `

Child Component

` }) export class ChildComponent { sayHello() { return "Hello from child!"; } }

parent.component.ts

import { ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';

@ViewChild(ChildComponent) child!: ChildComponent;

ngAfterViewInit() {
  console.log(this.child.sayHello());
}

7) Dynamic Component Loading (Advanced)

import { ViewContainerRef } from '@angular/core';

constructor(private vcr: ViewContainerRef) {}

loadComponent() {
  import('./card/card.component').then(({ CardComponent }) => {
    this.vcr.createComponent(CardComponent);
  });
}

8) Global Error Handler (Production)

import { ErrorHandler, Injectable } from '@angular/core';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  handleError(error: any) {
    console.error("Global Error:", error);
    // send error to server/log system
  }
}

Register:

providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }]

9) If and Nested If Conditions (TypeScript)

Simple if

let age = 20;

if (age >= 18) {
  console.log("Adult");
}

If else

if (age >= 18) {
  console.log("Adult");
} else {
  console.log("Minor");
}

Nested if

let marks = 85;

if (marks >= 35) {
  if (marks >= 90) {
    console.log("Grade A+");
  } else if (marks >= 75) {
    console.log("Grade A");
  } else {
    console.log("Grade B");
  }
} else {
  console.log("Fail");
}

10) If and Nested If Conditions in Angular HTML

Using *ngIf with else

<div *ngIf="isLoggedIn; else loginBlock">
  Welcome User!
</div>

<ng-template #loginBlock>
  Please login
</ng-template>

Nested *ngIf

<div *ngIf="isLoggedIn">
  <div *ngIf="isAdmin; else userBlock">
    Welcome Admin
  </div>

  <ng-template #userBlock>
    Welcome Normal User
  </ng-template>
</div>

11) Advanced RxJS: switchMap vs mergeMap (Interview)

this.searchControl.valueChanges.pipe(
  debounceTime(500),
  distinctUntilChanged(),
  switchMap(value => this.api.search(value))
);
switchMap cancels old request automatically.

12) Angular Signal + API (Modern Angular)

import { signal } from '@angular/core';

users = signal<any[]>([]);

loadUsers() {
  this.http.get<any[]>('/api/users').subscribe(res => {
    this.users.set(res);
  });
}

HTML:

<li *ngFor="let u of users()">{{ u.name }}</li>

13) JWT Role-Based Guard (Admin Only)

export const adminGuard: CanActivateFn = () => {
  const router = inject(Router);
  const role = localStorage.getItem("role");

  if (role !== "Admin") {
    router.navigate(['/unauthorized']);
    return false;
  }
  return true;
};

14) HTTP Retry + Error Handling

import { retry, catchError, throwError } from 'rxjs';

getData() {
  return this.http.get('/api/data').pipe(
    retry(2),
    catchError(err => throwError(() => err))
  );
}

✅ ULTRA PRO ANGULAR CODING EXERCISES (ALL)


1) Create a Custom Structural Directive (*appIf)

app-if.directive.ts

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appIf]'
})
export class AppIfDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) {}

  @Input() set appIf(condition: boolean) {
    this.viewContainer.clear();

    if (condition) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    }
  }
}

Usage:

<h2 *appIf="isLoggedIn">Welcome User</h2>

2) Custom Preloading Strategy (Lazy Loading Optimization)

custom-preload.strategy.ts

import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class CustomPreloadStrategy implements PreloadingStrategy {
  preload(route: Route, load: () => Observable<any>): Observable<any> {
    return route.data?.['preload'] ? load() : of(null);
  }
}

app-routing.module.ts

RouterModule.forRoot(routes, {
  preloadingStrategy: CustomPreloadStrategy
})

Route Example:

{
  path: 'admin',
  loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
  data: { preload: true }
}

3) Route Reuse Strategy (Cache Components Like Tabs)

custom-reuse.strategy.ts

import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {
  private storedRoutes = new Map<string, DetachedRouteHandle>();

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.routeConfig?.path === 'dashboard';
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    this.storedRoutes.set(route.routeConfig!.path!, handle);
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return this.storedRoutes.has(route.routeConfig!.path!);
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    return this.storedRoutes.get(route.routeConfig!.path!) || null;
  }

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig;
  }
}

Register:

providers: [{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }]

4) Angular CDK Virtual Scroll (For Huge Lists)

Install:

ng add @angular/cdk

HTML Example:

<cdk-virtual-scroll-viewport itemSize="50" style="height: 300px">
  <div *cdkVirtualFor="let user of users">
    {{ user.name }}
  </div>
</cdk-virtual-scroll-viewport>

5) Lazy Load Standalone Component (Angular 17+)

routes.ts

export const routes = [
  {
    path: 'profile',
    loadComponent: () =>
      import('./profile/profile.component').then(m => m.ProfileComponent)
  }
];

6) Micro Frontend Angular (Module Federation)

Install:

ng add @angular-architects/module-federation

Run Commands:

ng g @angular-architects/module-federation:init --project shell --type host
ng g @angular-architects/module-federation:init --project mfe1 --type remote
✅ Use case:
• Big enterprise apps
• Multiple teams working separately
• Deploy parts independently

7) NX Workspace (Monorepo) Setup

npx create-nx-workspace@latest
Inside NX:
• Multiple Angular apps
• Shared libs
• Better CI/CD
• Faster builds

8) Bundle Analyzer (Find Heavy Libraries)

Build Stats:

ng build --stats-json

Analyze:

npx webpack-bundle-analyzer dist/yourapp/stats.json

9) Advanced RxJS: Combine Multiple APIs with forkJoin

import { forkJoin } from 'rxjs';

loadDashboard() {
  forkJoin({
    users: this.http.get('/api/users'),
    invoices: this.http.get('/api/invoices'),
    projects: this.http.get('/api/projects')
  }).subscribe(result => {
    console.log(result.users, result.invoices, result.projects);
  });
}

10) Advanced RxJS: Caching API Calls using shareReplay

import { shareReplay } from 'rxjs/operators';

users$ = this.http.get('/api/users').pipe(
  shareReplay(1)
);
✅ API is called only once even with multiple subscribers.

11) HTTP Interceptor: Add JWT + Refresh Token (Pro)

auth.interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = localStorage.getItem("token");

    if (token) {
      req = req.clone({
        setHeaders: { Authorization: `Bearer ${token}` }
      });
    }

    return next.handle(req);
  }
}

Register:

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
]

12) Resolver: Load Data Before Route Opens

users.resolver.ts

import { ResolveFn } from '@angular/router';
import { inject } from '@angular/core';

export const usersResolver: ResolveFn<any> = () => {
  const http = inject(HttpClient);
  return http.get('/api/users');
};

routes.ts

{
  path: 'users',
  component: UsersComponent,
  resolve: { users: usersResolver }
}

component.ts

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  console.log(this.route.snapshot.data['users']);
}

13) Advanced Form Validation (Async Validator)

username.validator.ts

import { AbstractControl } from '@angular/forms';
import { map } from 'rxjs/operators';
import { inject } from '@angular/core';

export function usernameAsyncValidator() {
  const http = inject(HttpClient);

  return (control: AbstractControl) => {
    return http.get<any>(`/api/users/check/${control.value}`).pipe(
      map(res => (res.exists ? { usernameTaken: true } : null))
    );
  };
}

Usage:

this.form = this.fb.group({
  username: ['', null, [usernameAsyncValidator()]]
});

14) Dynamic Reactive Form (Add/Remove Controls)

component.ts

skills = this.fb.array([]);

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

addSkill() {
  this.skills.push(this.fb.control(''));
}

removeSkill(i: number) {
  this.skills.removeAt(i);
}

HTML:

<div formArrayName="skills">
  <div *ngFor="let s of skills.controls; let i=index">
    <input [formControlName]="i">
    <button (click)="removeSkill(i)">Remove</button>
  </div>
</div>

<button (click)="addSkill()">Add Skill</button>

15) Signal + Computed + Effect (Angular Modern)

import { signal, computed, effect } from '@angular/core';

count = signal(0);

doubleCount = computed(() => this.count() * 2);

constructor() {
  effect(() => {
    console.log("Count changed:", this.count());
  });
}

increment() {
  this.count.update(v => v + 1);
}

16) Pro-Level Nested If Conditions (Angular + TS)

TypeScript Nested If (Permissions Example):

if (this.isLoggedIn) {
  if (this.role === 'Admin') {
    console.log("Show Admin Dashboard");
  } else if (this.role === 'Manager') {
    console.log("Show Manager Dashboard");
  } else {
    console.log("Show User Dashboard");
  }
} else {
  console.log("Redirect to Login");
}

HTML Nested If (Permissions Example):

<div *ngIf="isLoggedIn; else loginBlock">

  <div *ngIf="role === 'Admin'; else notAdmin">
    <h2>Admin Dashboard</h2>
  </div>

  <ng-template #notAdmin>
    <div *ngIf="role === 'Manager'; else normalUser">
      <h2>Manager Dashboard</h2>
    </div>

    <ng-template #normalUser>
      <h2>User Dashboard</h2>
    </ng-template>
  </ng-template>

</div>

<ng-template #loginBlock>
  <h2>Please Login</h2>
</ng-template>

Comments

Popular posts from this blog

Debouncing & Throttling in RxJS: Optimizing API Calls and User Interactions

Promises in Angular

Comprehensive Guide to C# and .NET Core OOP Concepts and Language Features