Surya Rao Rayarao Blog

Code, Karma, and Creativity: A deeper look at tech's impact on our world

Mastering Angular Store Architecture: A Practical Guide

State management is a cornerstone of building robust, scalable, and maintainable Angular applications. As your app grows, managing data flow and state transitions can become complex and error-prone. This is where Angular store architecture comes in—a pattern that helps you centralize, organize, and control your application’s state in a predictable way.

In this post, you’ll learn:


What is Angular Store Architecture?

Angular store architecture refers to a design pattern where application state is managed in a single, centralized store. This approach is inspired by Redux and Flux patterns from the React ecosystem, but adapted for Angular using RxJS and Angular’s dependency injection.

Why use a store?


Core Concepts


Implementing a Simple Store with RxJS

Let’s build a minimal store from scratch using RxJS. This will help you understand the core ideas before using a library like NgRx.

import { BehaviorSubject, Observable } from 'rxjs';

interface AppState {
  counter: number;
}

const initialState: AppState = { counter: 0 };

class Store {
  private state$ = new BehaviorSubject<AppState>(initialState);

  // Selector
  select<K extends keyof AppState>(key: K): Observable<AppState[K]> {
    return this.state$.asObservable().pipe(map(state => state[key]));
  }

  // Action dispatcher
  setState(newState: Partial<AppState>) {
    this.state$.next({ ...this.state$.value, ...newState });
  }

  // Get current state snapshot
  get value() {
    return this.state$.value;
  }
}

// Usage
const store = new Store();
store.select('counter').subscribe(val => console.log('Counter:', val));
store.setState({ counter: 1 });

Tip: In a real app, you would inject the store as a service and use actions/reducers for more structure.


Using NgRx: The Official Angular Store Library

For large applications, NgRx is the de facto standard for state management in Angular. It provides a powerful set of tools based on Redux, but fully integrated with Angular and RxJS.

Key features:

Example: Counter Store with NgRx

// actions.ts
import { createAction } from '@ngrx/store';
export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');

// reducer.ts
import { createReducer, on } from '@ngrx/store';
export const initialState = 0;
const _counterReducer = createReducer(
  initialState,
  on(increment, state => state + 1),
  on(decrement, state => state - 1)
);
export function counterReducer(state, action) {
  return _counterReducer(state, action);
}

// selector.ts
import { createSelector } from '@ngrx/store';
export const selectCounter = (state) => state.counter;

Best Practice: Keep your state as flat as possible and use selectors to derive data for components.


Common Pitfalls & Best Practices


Summary & Key Takeaways


Further Reading


By mastering Angular store architecture, you’ll build apps that are easier to maintain, debug, and scale. Happy coding!