← Back to Chapters

State with Services

? State with Services

? Quick Overview

In Angular, services are commonly used to manage application state. Instead of passing data between components manually, a shared service acts as a central source of truth that any component can read from or update.

?️ Key Concepts

  • Service → Central place to store logic and state
  • BehaviorSubject → Holds current value and emits updates
  • Observable → Allows components to listen for changes
  • Dependency Injection → Service is injected into components
  • Single Source of Truth → One shared state across app

? Syntax / Theory

The recommended pattern for state management in Angular services:

  1. Create a BehaviorSubject to store the state
  2. Expose it as an Observable
  3. Modify state only inside service methods
  4. Subscribe in components to receive updates

? Code Example — State Service

? View Code Example
// state.service.ts - Centralized shared state service
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
providedIn: 'root'
})
export class StateService {
private messageSource = new BehaviorSubject<string>('Default Message');
currentMessage = this.messageSource.asObservable();

changeMessage(message: string) {
this.messageSource.next(message);
}
}

? Code Example — Using Service in Components

? View Code Example
// sender.component.ts - Updates shared state
import { Component } from '@angular/core';
import { StateService } from '../state.service';

@Component({
selector: 'app-sender',
template: '<button (click)="newMessage()">Change Message</button>'
})
export class SenderComponent {
constructor(private stateService: StateService) {}

newMessage() {
this.stateService.changeMessage('Hello from Sender!');
}
}

// receiver.component.ts - Reads shared state
import { Component, OnInit } from '@angular/core';
import { StateService } from '../state.service';

@Component({
selector: 'app-receiver',
template: '<p>Message: {{ message }}</p>'
})
export class ReceiverComponent implements OnInit {
message: string = '';

constructor(private stateService: StateService) {}

ngOnInit() {
this.stateService.currentMessage.subscribe(msg => this.message = msg);
}
}

? Live Output / Explanation

What Happens at Runtime?

  • Sender updates message in the service
  • BehaviorSubject emits new value
  • Receiver immediately receives update
  • No direct component-to-component communication
Reactive State Update

✅ Tips & Best Practices

  • Always expose state as Observable
  • Modify values only inside the service
  • Avoid direct component mutation
  • Prefer BehaviorSubject when you need current value
  • Keep services lightweight and reusable

? Try It Yourself

  • Create a CounterService with a number state
  • Add increment and decrement methods
  • Build two components — one updates counter, one displays it
  • Observe real-time update without manual syncing