myHotTake

Angular State Explained: Component vs. Application State

If this clicks with you, consider liking or sharing so others can enjoy too! 🌟


Think of component state and application state in Angular like running a hotel with individual guest rooms. Imagine I’m the hotel manager.

Each guest room represents a component, and in their rooms, guests control their own lights, temperature, and TV—this is the component state. It’s private and self-contained; what happens in one room doesn’t affect the others. For example, if a guest in Room 101 orders room service, it doesn’t mean Room 102 gets the same order.

But then, there’s the hotel lobby—this is the application state. The lobby holds shared information for everyone in the hotel, like the daily schedule, dining hours, or whether the pool is open. If I, as the manager, decide to close the pool, that change applies to everyone in the building because it’s part of the common state.

When guests check in (new components load) or check out (components unload), the lobby state remains consistent—it’s the foundation that keeps the whole hotel running smoothly. If a guest’s room state needs to know whether the pool is open, they just call down to the lobby to get the update.

So, in Angular, I keep track of the component state for localized, specific features and the application state for shared, global information. This way, my hotel—and my app—runs like a dream.


Component State: The Guest Room

In Angular, component state is defined within a specific component. Here’s an example of a room’s state where the guest controls the temperature:

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

@Component({
  selector: 'app-room',
  template: `
    <div>
      <h2>Room {{ roomNumber }}</h2>
      <p>Temperature: {{ temperature }}°C</p>
      <button (click)="increaseTemperature()">Increase Temperature</button>
      <button (click)="decreaseTemperature()">Decrease Temperature</button>
    </div>
  `,
})
export class RoomComponent {
  roomNumber = 101; // Local state for this room
  temperature = 22; // Initial temperature

  increaseTemperature() {
    this.temperature += 1;
  }

  decreaseTemperature() {
    this.temperature -= 1;
  }
}

Here, the state (temperature) is isolated. What happens in this component does not affect other rooms.


Application State: The Hotel Lobby

Now, let’s manage the application state in a shared service, like the hotel lobby’s central system. For this, we use an Angular service with BehaviorSubject to store global information, like whether the pool is open.

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

@Injectable({
  providedIn: 'root',
})
export class HotelService {
  private poolStatus = new BehaviorSubject<boolean>(true); // Shared application state
  poolStatus$ = this.poolStatus.asObservable();

  togglePoolStatus() {
    this.poolStatus.next(!this.poolStatus.value); // Toggle pool open/close
  }
}

This service acts as the lobby’s communication system. Any guest (component) can subscribe to the poolStatus$ observable and get real-time updates.


Connecting It All

Finally, let’s connect a room component to the shared application state:

import { Component } from '@angular/core';
import { HotelService } from './hotel.service';

@Component({
  selector: 'app-room',
  template: `
    <div>
      <h2>Room {{ roomNumber }}</h2>
      <p>Temperature: {{ temperature }}°C</p>
      <button (click)="increaseTemperature()">Increase Temperature</button>
      <button (click)="decreaseTemperature()">Decrease Temperature</button>

      <p>Is the pool open? {{ isPoolOpen ? 'Yes' : 'No' }}</p>
      <button (click)="togglePool()">Toggle Pool</button>
    </div>
  `,
})
export class RoomComponent {
  roomNumber = 101;
  temperature = 22;
  isPoolOpen = true;

  constructor(private hotelService: HotelService) {
    this.hotelService.poolStatus$.subscribe((status) => {
      this.isPoolOpen = status;
    });
  }

  increaseTemperature() {
    this.temperature += 1;
  }

  decreaseTemperature() {
    this.temperature -= 1;
  }

  togglePool() {
    this.hotelService.togglePoolStatus();
  }
}

Here, each room manages its own temperature (component state) while also checking the lobby’s pool status (application state). When the pool status changes, the update propagates to all subscribing components.


Key Takeaways

  1. Component State is local and specific to a component. It’s like the guest room—isolated and private.
  • Use it for UI controls or temporary data that doesn’t need to be shared.
  • Example: A form input value or button toggle within a component.
  1. Application State is global and shared across components. It’s like the hotel lobby—accessible to everyone.
  • Use it for data that needs to persist or be consistent across the app.
  • Example: User authentication status, global settings, or data shared between unrelated components.
  1. Angular Services and reactive programming with RxJS (BehaviorSubject, Observable) are powerful tools for managing application state efficiently.