liveBook · Manning

RxJS Subject

As explained in Modern Angular

An RxJS Subject is an observable that also acts as an observer, accepts published values, and multicasts them to subscribers.

An RxJS Subject is both an observable and an observer: it accepts published values and multicasts them to subscribers. In Angular, subjects support event streams and shared state that changes over time. section 5.2 section 1.2.1

Use subjects when an Angular application needs to:

  • Propagate authorization events or other changes between application areas. section 1.2.1
  • Represent user actions, such as approving, rejecting, or deleting a time-off request. section 7.3.4
  • Centralize asynchronous work in a service while keeping consuming components small and easy to test. section 7.3.4

Time-off management service

A state-management service can expose deleteRequest$, approveRequest$, and rejectRequest$ subjects. Each event can feed an RxJS pipeline that calls the corresponding request service, while a signal stores the resulting request state. Components inject the service, read its signals, and delegate user actions back to it. section 7.3.4

Listing 7.13 State management with advanced RxJS interoperability
@Injectable({ providedIn: 'root' })
export class TimeOffManagementService {
  private readonly timeOffRequestService = inject(TimeOffRequestService);












  deleteRequest$ = new Subject<TimeOffRequest>();  #1
  approveRequest$ = new Subject<TimeOffRequest>();
  rejectRequest$ = new Subject<TimeOffRequest>();
  selectedType = signal<
    'Vacation' | 'Sick Leave' |  'Maternity Leave' | 'Paternity Leave' | 'Other' | ''
  >((localStorage.getItem('selectedType') as any) ?? 
     '');  #2
  requests = toSignal(  #3
    merge(  #4
      toObservable(this.selectedType),  #5
      this.deleteRequest$.pipe(switchMap((r) => this.timeOffRequestService.deleteRequest(r.id))),  #6
      this.approveRequest$.pipe(switchMap((r) => this.timeOffRequestService.approveRequest(r.id))),
      this.rejectRequest$.pipe(switchMap((r) => this.timeOffRequestService.rejectRequest(r.id))),
    ).pipe(
      switchMap(() => {
        return this.timeOffRequestService
          .getRequestsByType(  #7
            this.selectedType(),
          );
      })
    ),
    {
      initialValue: [] as TimeOffRequest[],
    }
  );
  resolvedRequests = computed(() =>
    this.requests().filter((r) => r.status !== 'Pending')
  );

  constructor() {  #8
    effect(() => {
      localStorage.setItem('selectedType', this.selectedType());
    });
  }

  approveRequest(request: TimeOffRequest) {
    this.approveRequest$.next(request);  #9
  }

  rejectRequest(request: TimeOffRequest) {
    this.rejectRequest$.next(request);
  }

  deleteRequest(request: TimeOffRequest) {
    this.deleteRequest$.next(request);
  }
}

Inspect the complete state-management listing to see subjects connected to request operations and signal-based state. section 7.3.4

How Modern Angular covers it

How deep it goes
Explains subjects through event-driven services and their relationship with observables and signals, without detailing Subject internals.
Examples
Demonstrates authorization changes and time-off request approval, rejection, and deletion events.
What it assumes
Assumes familiarity with Angular applications and introduces subjects alongside observables, operators, services, and signals.
What you can do after
Apply RxJS subjects in a service to publish domain events and coordinate asynchronous operations with shared state.
How it connects
Connects subjects with observables, RxJS operators, Angular services, signals, and state management.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern Angular. The section links point to the parts of the book it draws on.