NashTech Insights

Managing States with Services and Observables in Angular

Picture of Alka Vats
Alka Vats
Table of Contents

Introduction

As Angular applications grow in complexity, managing states become increasingly challenging. To address this issue, Angular provides a powerful and efficient way to manage forms using services and observables. This blog will explore how to manage states in Angular applications using services and observables, along with practical examples.

If you want to learn more about the Principles and Concepts of Functional Programming, please refer here.

Understanding State Management in Angular

State management in Angular refers to managing and sharing data between different components and services. As an application evolves, components may need to communicate with each other, share data, or react to changes in the application state. Services and observables play a significant role in handling these scenarios efficiently.

Using Services for State Management

Services are Angular constructs that facilitate communication between components by providing a shared data store. They act as a central hub for managing the application state and are designed to be singleton instances, meaning there is only one instance of the service throughout the application.

Example: Creating a State Service

Let’s create a simple state service that stores and manages a list of items.

Step 1: Generate a State Service

Use the Angular CLI to generate a new service called state:

ng generate service state
Step 2: Implement the State Service

Open the state.service.ts file and add the necessary code:

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

@Injectable({
  providedIn: 'root',
})
export class StateService {
  private items: string[] = [];

  addItem(item: string): void {
    this.items.push(item);
  }

  getItems(): string[] {
    return this.items;
  }

  clearItems(): void {
    this.items = [];
  }
}
Step 3: Use the State Service in Components

Now, let’s use the state service in two components: AddItemComponent and ListItemsComponent.

import { Component } from '@angular/core';
import { StateService } from '../state.service';

@Component({
  selector: 'app-add-item',
  template: `
    <input type="text" [(ngModel)]="newItem">
    <button (click)="addItem()">Add Item</button>
  `,
})
export class AddItemComponent {
  newItem = '';

  constructor(private stateService: StateService) {}

  addItem(): void {
    this.stateService.addItem(this.newItem);
    this.newItem = '';
  }
}
import { Component } from '@angular/core';
import { StateService } from '../state.service';

@Component({
  selector: 'app-list-items',
  template: `
    <ul>
      <li *ngFor="let item of items">{{ item }}</li>
    </ul>
    <button (click)="clearItems()">Clear Items</button>
  `,
})
export class ListItemsComponent {
  constructor(private stateService: StateService) {}

  get items(): string[] {
    return this.stateService.getItems();
  }

  clearItems(): void {
    this.stateService.clearItems();
  }
}

Using Observables for State Management

Observables are a powerful tool for handling asynchronous operations and managing state changes in Angular applications. They provide a way to subscribe to changes in data and react accordingly.

Example: Creating an Observable State Service

Let’s extend the previous example by using an observable to manage the state of items.

Step 1: Update the State Service

Modify the state.service.ts file to use an observable for item updates:

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

@Injectable({
  providedIn: 'root',
})
export class StateService {
  private itemsSubject = new BehaviorSubject<string[]>([]);
  items$ = this.itemsSubject.asObservable();

  addItem(item: string): void {
    const currentItems = this.itemsSubject.getValue();
    this.itemsSubject.next([...currentItems, item]);
  }

  clearItems(): void {
    this.itemsSubject.next([]);
  }
}
Step 2: Use the Observable State Service in Components

Update the ListItemsComponent to subscribe to changes in the items observable:

import { Component, OnDestroy } from '@angular/core';
import { StateService } from '../state.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-list-items',
  template: `
    <ul>
      <li *ngFor="let item of items">{{ item }}</li>
    </ul>
    <button (click)="clearItems()">Clear Items</button>
  `,
})
export class ListItemsComponent implements OnDestroy {
  items: string[] = [];
  private subscription: Subscription;

  constructor(private stateService: StateService) {
    this.subscription = this.stateService.items$.subscribe((items) => {
      this.items = items;
    });
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  clearItems(): void {
    this.stateService.clearItems();
  }
}

Conclusion

State management is a critical aspect of Angular development, and using services and observables can greatly simplify the process. In this blog, we explored how to use services to manage states and how to leverage observables for asynchronous state management. By creating a centralized state service and using observables to handle state changes, you can build scalable and maintainable Angular applications.

Remember to use services and observables judiciously, and adopt best practices to ensure optimal performance and a smooth user experience. By following the examples and guidelines provided, you can effectively manage the state of your Angular applications and deliver exceptional user interactions. Happy coding with Angular state management!

Finally, for more such posts, please follow our LinkedIn page- FrontEnd Competency.

Picture of Alka Vats

Alka Vats

Alka Vats is a Software Consultant at Nashtech. She is passionate about web development. She is recognized as a good team player, a dedicated and responsible professional, and a technology enthusiast. She is a quick learner & curious to learn new technologies. Her hobbies include reading books, watching movies, and traveling.

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article