πŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
πŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Singleton Services in Angular

Learn about Singleton Services in this comprehensive Angular tutorial. Master the use of singletons for data persistence and cross-component communication, and learn how to build reactive services using RxJS Subjects.

⚑ Total XP: 0|πŸ’» angular XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

πŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
πŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

The singleton pattern is the 'Superpower' of Angular. It allows you to create a centralized state that acts as the single source of truth for your entire application.

1State Persistence

One of the biggest challenges in SPA (Single Page Application) development is keeping data alive while the user moves around. Since components are destroyed and recreated during navigation, you cannot store long-term data inside them. Singleton services live as long as the application is running. By moving your application state into a service, you ensure that the user's progress is never lost as they move through your routes.

2The Observable Service Pattern

While a simple property in a service can store data, it isn't 'reactive'. Components would have to constantly poll the service to see if the value changed. By using a BehaviorSubject, you turn your singleton into a broadcaster. Components 'subscribe' to the data stream and are automatically notified (and updated) the millisecond the service data changes. This is the foundation of high-performance Angular UI.

3Step-by-Step Breakdown

Singletons are the backbone of Angular state management. A singleton is a service where exactly one instance exists for the entire application.

Because it's a singleton, the data inside the service persists even when you navigate between different pages/routes.

Let's see it in action. Component A updates a 'counter' in the service. Component B, on a different page, sees the updated value.

Checkpoint: If a service is a Singleton, what happens to its data when the user navigates to a new route?

  • β†’The data is reset to its initial state
  • β†’The data persists and is still available

This makes singletons perfect for storing things like: User Authentication status, Shopping Cart items, or Theme preferences.

To make a singleton truly reactive, we often combine it with RxJS Subjects. This allows components to 'listen' for changes in real-time.

Checkpoint: Which RxJS class is commonly used in singleton services to broadcast state changes to subscribers?

  • β†’Basic Observable
  • β†’BehaviorSubject

Magnificent! You've mastered the heart of Angular's architecture. Your apps are now connected, reactive, and efficient.

Congratulations! You've finished the Services and DI chapter. Next, we'll dive into the world of Routing!

Level Up πŸš€

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1A Singleton State Store Is an Ideal Home for App-Wide Accessibility Preferences

Something like a user's 'reduce motion' or 'high contrast' preference is naturally app-wide state β€” a singleton service is exactly the right pattern to store it once and let every component reactively respect it, rather than each component re-reading a media query independently.

2A Singleton's Shared State Changing Should Trigger Announcements Where Relevant

If a singleton service's state change should be perceivable (a global 'unsaved changes' flag, a notification count), pair the state update with an explicit `aria-live` announcement in whichever component surfaces that change, since the store itself has no way to speak to the user directly.

SEO Implications

  • 1

    A Root-Provided Singleton Is Tree-Shakeable if Never Actually Injected Anywhere

    `providedIn: 'root'` services are only included in the final bundle if something actually injects them β€” an unused singleton service is automatically excluded, keeping bundle size (and therefore Time to Interactive) as small as the app's actual dependency graph requires.

  • 2

    Singleton State Holding Per-Request Data Is a Correctness Risk Specifically Under SSR

    A single Node.js process handling Angular Universal's server-side rendering can serve multiple concurrent users' requests β€” a singleton holding mutable per-user state can leak between them unless carefully scoped, a bug class that simply can't happen in a purely client-side single-user browser context.

Best Practices

Back Singleton State With a `BehaviorSubject`, Not a Plain Property

A `BehaviorSubject` immediately gives late subscribers the current value on subscription and lets every consumer reactively receive future updates β€” a plain property offers neither, forcing consumers to manually re-check it or miss updates entirely.

Expose Only a Read-Only Observable Publicly, Keep the Mutable Subject Private

Exposing `cartCount$ = this.count.asObservable()` (read-only) while keeping the underlying `BehaviorSubject` private forces all state changes to go through the service's own explicit methods, preventing external code from directly pushing arbitrary values into the shared state.

Frequent Bugs

THE BUG

A singleton service's state appears to reset unexpectedly when navigating to a lazy-loaded feature module.

THE FIX

The service is being re-provided in the lazy-loaded module's own `providers` array, creating a second, separate instance scoped to that module's child injector rather than sharing the app-wide singleton β€” remove the duplicate provider declaration so the lazy module resolves the existing root instance instead.

THE BUG

External code can push arbitrary invalid values directly into what's supposed to be centrally-managed shared state.

THE FIX

The service exposed its internal `BehaviorSubject` directly rather than a read-only `Observable` derived from it β€” any consumer with a reference to the raw Subject can call `.next()` on it themselves, bypassing any validation logic the service's own methods were meant to enforce. Expose only `.asObservable()` publicly and keep the mutable Subject private.

Real-World Examples

App-Wide Accessibility Preference Store

A singleton service centralizes the user's 'reduce motion' preference, read once from system settings or user choice, letting every component across the app reactively respect it without independently querying media features.

@Injectable({ providedIn: 'root' })
export class PreferencesService {
  private reduceMotion = new BehaviorSubject(matchMedia('(prefers-reduced-motion: reduce)').matches);
  reduceMotion$ = this.reduceMotion.asObservable();
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Memory leaks from unclosed Subscriptions

// Wrong ngOnInit() { this.dataService.getData().subscribe(data => this.data = data); } // Correct ngOnInit() { this.sub = this.dataService.getData().subscribe(data => this.data = data); } ngOnDestroy() { if (this.sub) this.sub.unsubscribe(); }

The Solution //

When subscribing to Observables in a component, always unsubscribe in the ngOnDestroy hook to prevent memory leaks.

The Error //

Directly manipulating the DOM

// Wrong document.getElementById('my-el').style.color = 'red'; // Correct @ViewChild('myEl') myEl: ElementRef; this.renderer.setStyle(this.myEl.nativeElement, 'color', 'red');

The Solution //

Avoid using document.getElementById or native DOM APIs. Use Angular's templating, bindings, and tools like Renderer2 or ViewChild.

Lesson Glossary

[01]Singleton

A class that is instantiated only once and shared across the entire application context.

Code Preview
Global

[02]Source of Truth

The architectural practice of having one single location where a specific piece of data is managed.

Code Preview
One Place

[03]State Persistence

The ability of data to remain available across different component lifecycles or route changes.

Code Preview
Memory

[04]BehaviorSubject

An RxJS Subject that requires an initial value and emits its current value to new subscribers.

Code Preview
Reactive

[05]Centralized State

Storing application logic and data in a shared service rather than individual components.

Code Preview
Management

[06]Subscription

The act of connecting a component to a data stream provided by a service.

Code Preview
Listen

Continue Learning