Skip to main content
Angular Basics
CHAPTER 29 Beginner

Advanced Angular Concepts

Updated: May 18, 2026
5 min read

# CHAPTER 29

Advanced Angular Concepts

1. Chapter Introduction

This chapter explores the cutting-edge features of modern Angular. These concepts separate senior Angular developers from mid-level developers. We cover Angular Signals (the future of reactivity), advanced standalone architecture, dynamic component rendering, and advanced RxJS patterns.

2. Learning Objectives

  • Understand and use Angular Signals (signal, computed, effect).
  • Build apps with fully standalone components.
  • Create dynamic components programmatically.
  • Use advanced RxJS patterns.
  • Understand custom Angular libraries.

3. Angular Signals (v16+)

Signals are a new reactive primitive that makes Angular's reactivity model simpler and more performant. Unlike Observables which require subscription management, Signals automatically track dependencies.
typescript
123456789101112131415161718192021222324252627282930
import { Component, signal, computed, effect } from '@angular/core';

@Component({
  standalone: true,
  selector: 'app-counter',
  template: `
    <h2>Count: {{ count() }}</h2>
    <h3>Double: {{ double() }}</h3>
    <button (click)="increment()">+1</button>
  `
})
export class CounterComponent {
  // signal() — wraps a reactive value
  count = signal<number>(0);

  // computed() — automatically updates when 'count' changes
  double = computed(() => this.count() * 2);

  constructor() {
    // effect() — runs side effects when signals change
    effect(() => {
      console.log(&#039;Count changed to:&#039;, this.count());
    });
  }

  increment(): void {
    this.count.update(c => c + 1); // update() applies a function
    // OR: this.count.set(this.count() + 1); // set() sets directly
  }
}

4. Signals with HTTP (Signal-based Services)

typescript
123456789101112131415161718192021
import { Injectable, signal } from &#039;@angular/core&#039;;

@Injectable({ providedIn: &#039;root&#039; })
export class ProductSignalService {
  private _products = signal<any[]>([]);
  private _loading = signal<boolean>(false);

  // Public read-only access
  readonly products = this._products.asReadonly();
  readonly loading = this._loading.asReadonly();

  constructor(private http: HttpClient) {}

  loadProducts(): void {
    this._loading.set(true);
    this.http.get<any[]>(&#039;/api/products&#039;).subscribe({
      next: p => { this._products.set(p); this._loading.set(false); },
      error: () => this._loading.set(false)
    });
  }
}
html
1234567
@if (productService.loading()) {
  <p>Loading...</p>
} @else {
  @for (p of productService.products(); track p.id) {
    <div>{{ p.name }}</div>
  }
}

5. Standalone Components at Scale

typescript
1234567
// Modern Angular app with no NgModules at all
// main.ts
import { bootstrapApplication } from &#039;@angular/platform-browser&#039;;
import { AppComponent } from &#039;./app/app.component&#039;;
import { appConfig } from &#039;./app/app.config&#039;;

bootstrapApplication(AppComponent, appConfig);
app.config.ts
1234567
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withPreloading(PreloadAllModules)),
    provideHttpClient(withInterceptors([authInterceptor])),
    provideAnimations()
  ]
};
feature.component.ts
1234567
@Component({
  standalone: true,
  selector: &#039;app-feature&#039;,
  imports: [CommonModule, RouterModule, SharedButtonComponent], // Direct imports!
  template: `...`
})
export class FeatureComponent {}

6. Dynamic Components (ViewContainerRef)

Sometimes you need to programmatically create components at runtime (like a dialog or notification system):
typescript
123456789101112131415161718
import { Component, ViewContainerRef, ComponentRef } from &#039;@angular/core&#039;;
import { AlertComponent } from &#039;./alert.component&#039;;

@Component({ selector: &#039;app-root&#039;, template: &#039;<button (click)="showAlert()">Alert</button><ng-container #container></ng-container>&#039; })
export class AppComponent {
  private alertRef?: ComponentRef<AlertComponent>;

  constructor(private vcr: ViewContainerRef) {}

  showAlert(): void {
    this.vcr.clear();
    this.alertRef = this.vcr.createComponent(AlertComponent);
    this.alertRef.instance.message = &#039;Dynamic alert created!&#039;;
    this.alertRef.instance.closed.subscribe(() => {
      this.alertRef?.destroy();
    });
  }
}

7. Advanced RxJS Patterns

#### combineLatest — React to multiple streams

typescript
1234567
// Dashboard that needs both user AND products simultaneously
combineLatest([
  this.userService.currentUser$,
  this.productService.products$
]).subscribe(([user, products]) => {
  this.dashboardData = { user, products };
});

#### withLatestFrom — Combine with latest from another stream

typescript
1234
this.saveButton$.pipe(
  withLatestFrom(this.form.valueChanges),
  switchMap(([_, formData]) => this.api.save(formData))
).subscribe();

#### Custom Operators

typescript
123456789101112131415
// Reusable operator for retry with delay
export function retryWithDelay(maxRetries = 3, delay = 1000) {
  return <T>(source: Observable<T>): Observable<T> =>
    source.pipe(
      retryWhen(errors =>
        errors.pipe(
          take(maxRetries),
          delayWhen(() => timer(delay))
        )
      )
    );
}

// Usage
this.http.get(&#039;/api/data&#039;).pipe(retryWithDelay(3, 2000)).subscribe();

8. Angular Signals vs RxJS

FeatureSignalsRxJS Observables
Learning curveSimpleSteep
SynchronousYesNo (by default)
Async streamsLimitedExcellent
Change detectionAutomatic, fine-grainedManual subscription
HTTPNeeds RxJS bridgeNative
Use forUI state, derived valuesComplex async, HTTP

*Best practice: Use Signals for UI state, continue using RxJS for HTTP and complex async streams.*

9. Common Mistakes

  • Calling signal value without (): count() reads the signal. count without parentheses is the signal object itself.
  • Using mutable operations on signal arrays: this.items().push(x) is wrong. Always: this.items.update(arr => [...arr, x]).

10. MCQs with Answers

Question 1

What is an Angular Signal?

Question 2

How do you READ a signal value in a template?

Question 3

What function creates a derived value that auto-updates when its signal dependencies change?

Question 4

What function runs a side effect whenever a signal's value changes?

Question 5

What method immutably updates a signal by applying a function to the current value?

Question 6

In a Standalone Component, how do you use a component from another module?

Question 7

What is ViewContainerRef used for?

Question 8

What RxJS operator combines the LATEST values from multiple Observables whenever any of them emit?

Question 9

What function bootstraps a standalone Angular application without an AppModule?

Question 10

When should you use Signals vs RxJS?

11. Interview Questions

  • Q: How do Angular Signals improve on the traditional change detection approach?
  • Q: Explain the difference between set(), update(), and mutate() on a Signal.

12. Summary

Modern Angular is evolving rapidly. Signals represent the future of Angular's reactivity model, providing simpler state management with automatic change detection. Standalone components eliminate NgModule complexity. These advanced features are what separate Angular 17+ apps from legacy Angular 8 codebases.

13. Next Chapter Recommendation

Congratulations on reaching the final chapter! In Chapter 30: Final Projects and Real-World Applications, we review complete project blueprints — from an ecommerce frontend to an admin dashboard — to solidify everything you have learned.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·