Skip to content

Repository files navigation

Grandgular Logo

@grandgular/rx

License: MIT

@grandgular/rx extends RxJS with Angular-optimized operators, providing enhanced reactive programming capabilities for Angular applications.

Features

  • 🧠 Stateful Operators – Advanced operators with configurable memory and state management
  • Angular-First – Designed to work seamlessly with Angular's change detection and lifecycle
  • 🏎️ Performance-Optimized – Minimal overhead, maximum efficiency for high-frequency streams
  • 🛠️ Type-Safe – Full TypeScript support with strict interfaces
  • 🔄 Reactive Patterns – Simplify common RxJS challenges in Angular apps
  • 📦 Lightweight – Tiny bundle size with zero unnecessary dependencies

Community & Support

🔹 Angular Community:
Join our Telegram channel for Angular tips and discussions:
Telegram

🔹 Author:
Connect with me on LinkedIn:
LinkedIn


Quick Navigation

tapFirst
log
distinctUntilChangedWithMemory
redirectOnHttpError


Installation

npm install @grandgular/rx

Operators

tapFirst()

An enhanced version of RxJS's tap() that executes side-effects only for the first emitted value, with optional state isolation for individual subscribers.

Key Features:

  • Selective side-effects - Execute callbacks only for the first value in the stream
  • Dual mode operation - Choose between shared or isolated state per subscriber
  • Memory efficient - No additional subscriptions or complex state management
  • Type-safe - Full TypeScript support with proper generics
  • RxJS native - Seamlessly integrates with existing RxJS pipelines

Usage Examples:

1. Basic Usage (Shared State)
import{of}from"rxjs";import{tapFirst}from"./tap-first";constshared$=of(1,2,3);shared$.pipe(tapFirst((value)=>console.log("First value detected:",value))).subscribe(console.log);// Output:// First value detected: 1// 1// 2// 3
2. Isolated State for Multiple Subscribers
constnumbers$=of(10,20,30);// Isolated stateconstisolated$=numbers$.pipe(tapFirst((val)=>console.log("Isolated first:",val),true));isolated$.subscribe();// Logs: "Isolated first: 10"isolated$.subscribe();// Logs: "Isolated first: 10" - fresh state for each subscriber

log()

A custom RxJS operator for logging stream values, errors, and completion events.
Useful for inspecting observable streams without modifying their data flow.

Usage Example:

import{of}from"rxjs";import{log}from"@grandgular/rx";// Logs values and completion as-isof(1,2,3).pipe(log()).subscribe();// output: 1// output: 2// output: 3// output: Completed// Logs with a prefix for easier identificationof(4,Error("not 5"),6).pipe(log("MyStream")).subscribe();// output: [MyStream] 4// output: [MyStream] Error: not 5// output: [MyStream] 6// output: [MyStream] Completed// Logs using a custom formatter functionof(7,8,9).pipe(log((v)=>v*1000)).subscribe();// output: 7000// output: 8000// output: 9000// output: Completed

distinctUntilChangedWithMemory()

An enhanced version of RxJS's distinctUntilChanged() that maintains a memory of previous values, allowing for more sophisticated duplicate detection.

Key Features:

  • Configurable memory size - Remember last N values (default: Infinity)
  • Custom comparison - Define your own duplicate detection logic
  • Angular-optimized - Works seamlessly with Angular's change detection
  • Type-safe - Full TypeScript support

Usage Examples:

1. Infinite Memory
constnums$=of(1,2,3,4,1,2,5);nums$.pipe(distinctUntilChangedWithMemory(),// Defaults to Infinity).subscribe(console.log);// Output: 1, 2, 3, 4, 5
2. Basic Deduplication (Remember last 3 values)
constsource$=of(1,2,3,1,2,3,4,3,5);source$.pipe(distinctUntilChangedWithMemory(3),// Remember last 3 values).subscribe(console.log);// Output: 1, 2, 3, 4, 5// Explanation: The second '1' and '2' are filtered because they're in the memory
3. Case-Insensitive String Comparison
constwords$=of("Apple","Banana","apple","orange","Apple");words$.pipe(distinctUntilChangedWithMemory({memorySize: 4,comparator: (prev,curr)=>prev.some((word)=>word.toLowerCase()===curr.toLowerCase()),}),).subscribe(console.log);// Output: 'Apple', 'Banana', 'orange'

redirectOnHttpError()

An RxJS operator that handles HTTP errors by redirecting to specified routes based on error status codes, while maintaining the original error for downstream processing.

Key Features:

  • Status-based routing - Map specific HTTP status codes to different routes
  • Flexible configuration - Accepts either a route map or a single fallback route
  • History control - Option to skip location change in browser history
  • Error logging - Optional callback for error logging
  • Type-safe - Full TypeScript support with HttpStatusCode enum

Usage Examples:

1. Basic Usage with Fallback Route
import{redirectOnHttpError}from"./path/to/operator";this.http.get("/api").pipe(redirectOnHttpError(this.router,{redirectConfig: "/error",// Single fallback route}),).subscribe({next: (data)=>handleData(data),error: (err)=>console.error("Original error preserved:",err),});
2. Status-Specific Routing
this.http.get("/api").pipe(redirectOnHttpError(this.router,{redirectConfig: {[HttpStatusCode.NotFound]: "/not-found",[HttpStatusCode.Forbidden]: "/access-denied",default: "/server-error",},skipLocationChange: true,// Won't add to browser history}),).subscribe();
3. With Error Logging
this.http.post("/api",payload).pipe(redirectOnHttpError(this.router,{redirectConfig: {[HttpStatusCode.BadRequest]: "/invalid-request",default: "/error",},logError: (error)=>this.errorService.log(error),// Custom logging}),).subscribe();

Configuration Options:

OptionTypeDescription
redirectConfigstring OR ErrorRoutesTypesEither a single fallback route or a map of status codes to routes (must include 'default')
skipLocationChangeboolean (optional)If true, navigation won't push a new state into browser history (default: false)
logError(error: unknown) => void (optional)Callback for custom error logging

License

MIT © Grandgular

About

Enhanced RxJS operators for Angular — tapFirst, distinctUntilChangedWithMemory, redirectOnHttpError, and more.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages