Blog>
Snippets

Micro-Frontend State Management with Redux

Provide an example of using a global state management like NgRx/Redux in the context of an Angular micro-frontend application.
import { createAction, props } from '@ngrx/store';

// Define an action to set the username
export const setUsername = createAction(
  '[User] Set Username',
  props<{ username: string }>()
);
Defines an NgRx action for setting a username within the global state.
import { createReducer, on } from '@ngrx/store';
import * as UserActions from './user.actions';

export interface UserState {
  username: string;
}

export const initialState: UserState = {
  username: '',
};

export const userReducer = createReducer(
  initialState,
  on(UserActions.setUsername, (state, { username }) => ({ ...state, username }))
);
Creates a reducer to handle the action which sets the username in the user's slice of the state.
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { userReducer } from './user.reducer';

@NgModule({
  imports: [
    StoreModule.forFeature('user', userReducer),
  ],
})
export class UserStateModule {}
Sets up an NgRx feature module for user state that can be imported into an Angular micro-frontend.
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { setUsername } from './user.actions';
import { UserState } from './user.reducer';

@Injectable({
  providedIn: 'root',
})
export class UserService {
  constructor(private store: Store<{ user: UserState }>) {}

  // Dispatch an action to set the username
  updateUsername(newUsername: string) {
    this.store.dispatch(setUsername({ username: newUsername }));
  }
}
Defines a service that provides methods to interact with the store, specifically to dispatch an action to set the username.
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { UserState } from './store/user.reducer';

@Component({
  selector: 'app-user-display',
  template: `<div>Username: {{ username$ | async }}</div>`,
})
export class UserDisplayComponent {
  username$: Observable<string>;

  constructor(private store: Store<{ user: UserState }>) {
    this.username$ = this.store.select(state => state.user.username);
  }
}
Defines an Angular component which uses the store to select and display the username as an observable.