Skip to main content
The NotificationsStore is an Angular service that manages a list of notifications using Angular signals. It provides reactive properties and methods to add and clear notifications.

Overview

This injectable service uses Angular’s signal API to provide reactive notification management. The store maintains an internal list of notifications and exposes computed properties for reactive updates. Source: src/app/shared/services/state/notifications.store.ts

Computed properties

notifications

notifications: Signal<Notification[]>
A readonly signal containing the current list of notifications.
notifications
Signal<Notification[]>
required
Readonly signal array of all notifications in the store

count

count: Signal<number>
A computed signal that returns the number of notifications in the store.
count
Signal<number>
required
Computed signal with the total count of notifications

Methods

addNotification()

addNotification(notification: Notification): void
Adds a new notification to the list.
notification
Notification
required
The notification object to add to the store
Behavior:
  • Appends the notification to the end of the existing list
  • Triggers reactivity for all computed properties
  • Does not check for duplicates
return
void
No return value

clearNotifications()

clearNotifications(): void
Removes all notifications from the store. Behavior:
  • Sets the internal state to an empty array
  • Resets the count to 0
  • Triggers reactivity for all computed properties
return
void
No return value

Usage example

Basic notification management

import { Component, inject } from '@angular/core';
import { NotificationsStore } from '@services/state/notifications.store';
import { Notification } from '@domain/notification.type';

@Component({
  selector: 'app-notifications',
  template: `
    <div class="notifications-panel">
      <h3>Notifications ({{ notificationsStore.count() }})</h3>
      
      @for (notification of notificationsStore.notifications(); track notification.id) {
        <div class="notification" [class]="notification.type">
          <p>{{ notification.message }}</p>
        </div>
      }
      
      @if (notificationsStore.count() > 0) {
        <button (click)="clearAll()">Clear All</button>
      }
    </div>
  `
})
export class NotificationsComponent {
  notificationsStore = inject(NotificationsStore);

  clearAll() {
    this.notificationsStore.clearNotifications();
  }
}

Adding notifications

import { Component, inject } from '@angular/core';
import { NotificationsStore } from '@services/state/notifications.store';
import { Notification } from '@domain/notification.type';

@Component({
  selector: 'app-user-actions',
  template: `
    <button (click)="saveData()">Save</button>
    <button (click)="deleteData()">Delete</button>
  `
})
export class UserActionsComponent {
  notificationsStore = inject(NotificationsStore);

  saveData() {
    // Perform save operation
    // ...
    
    // Add success notification
    const notification: Notification = {
      id: Date.now(),
      message: 'Data saved successfully',
      type: 'success',
      timestamp: new Date()
    };
    
    this.notificationsStore.addNotification(notification);
  }

  deleteData() {
    // Perform delete operation
    // ...
    
    // Add warning notification
    const notification: Notification = {
      id: Date.now(),
      message: 'Data deleted',
      type: 'warning',
      timestamp: new Date()
    };
    
    this.notificationsStore.addNotification(notification);
  }
}

Notification badge

import { Component, inject } from '@angular/core';
import { NotificationsStore } from '@services/state/notifications.store';

@Component({
  selector: 'app-header',
  template: `
    <header>
      <button class="notification-bell">
        <span class="icon">🔔</span>
        @if (notificationsStore.count() > 0) {
          <span class="badge">{{ notificationsStore.count() }}</span>
        }
      </button>
    </header>
  `
})
export class HeaderComponent {
  notificationsStore = inject(NotificationsStore);
}

Error handling with notifications

import { inject } from '@angular/core';
import { HttpInterceptorFn } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { NotificationsStore } from '@services/state/notifications.store';

export const errorInterceptor: HttpInterceptorFn = (req, next) => {
  const notificationsStore = inject(NotificationsStore);

  return next(req).pipe(
    catchError((error) => {
      // Add error notification
      notificationsStore.addNotification({
        id: Date.now(),
        message: error.message || 'An error occurred',
        type: 'error',
        timestamp: new Date()
      });

      return throwError(() => error);
    })
  );
};

Notification type

The Notification type should be defined in your domain types. A typical structure might include:
export interface Notification {
  id: number;
  message: string;
  type: 'success' | 'error' | 'warning' | 'info';
  timestamp: Date;
}

Build docs developers (and LLMs) love