Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
13 posts found
Understanding RxJS Observables from the Inside: The Contract, Laziness, Teardown and Your Own 40-Line Observable
Frontend PART 01

Understanding RxJS Observables from the Inside: The Contract, Laziness, Teardown and Your Own 40-Line Observable

An Observable is a push function that does nothing until you subscribe and runs its producer again on every subscribe; it may send next values followed by at most one error or complete. We show the contract, synchronous and asynchronous emission, teardown, and why two subscribes to the same HTTP Observable send two requests, using a real server log, then write our own 40-line Observable.

14 Nov 2026 15 min 11
RxJS Creation Functions and Cold vs Hot Observables: of, from, defer, timer, fromEvent and iif
Frontend PART 02

RxJS Creation Functions and Cold vs Hot Observables: of, from, defer, timer, fromEvent and iif

A cold Observable restarts its producer for each subscriber, while a hot one attaches subscribers to a source that flows on its own; to wrap Promise-based work in an Observable, use defer, not from. We compare of, from, range, defer, iif, EMPTY, NEVER, throwError, timer, interval, fromEvent and fromFetch with a real server log, and show why retry with from(promise) sends no new request.

14 Nov 2026 15 min 12
Reading Marble Diagrams and the Core Operators: map, filter, scan, take and distinctUntilChanged
Frontend PART 03

Reading Marble Diagrams and the Core Operators: map, filter, scan, take and distinctUntilChanged

A marble diagram shows an Observable's values, completion and error over time on one line; a pipeable operator is a function that takes an Observable and returns a new one. We examine map, scan, reduce, pairwise, filter, takeWhile, skip, first, last and distinctUntilChanged with marbles verified by TestScheduler, and show the EmptyError and object comparison traps with Bookstore's cart and catalog filter.

14 Nov 2026 14 min 12
Higher-Order Mapping: Choosing Between switchMap, mergeMap, concatMap and exhaustMap
Frontend PART 04

Higher-Order Mapping: Choosing Between switchMap, mergeMap, concatMap and exhaustMap

Use switchMap for reads where only the latest value matters, such as search; concatMap for writes whose order matters; exhaustMap for actions that must not repeat; and a limited mergeMap for independent work. We compare the four operators with the same marble, run them in virtual time on Bookstore's search box, cart quantity, double-clicked Place Order button and 50 cover downloads, and show why switchMap is dangerous for POSTs.

14 Nov 2026 16 min 12
Combining Streams in RxJS: combineLatest, withLatestFrom, forkJoin, zip, merge and concat
Frontend PART 05

Combining Streams in RxJS: combineLatest, withLatestFrom, forkJoin, zip, merge and concat

combineLatest gives the latest value of each source, withLatestFrom the context when a trigger fires, forkJoin the results once all complete, zip values by position, merge every value as it comes, concat sources in order, and race the first to emit. We turn Bookstore's catalog filters into one query with combineLatest and startWith, load order details in parallel with forkJoin, and show the silent-source, never-completing and empty-array traps in virtual time.

14 Nov 2026 14 min 9
Time-Based Operators and Schedulers: debounceTime, throttleTime, auditTime, timeout and Polling
Frontend PART 06

Time-Based Operators and Schedulers: debounceTime, throttleTime, auditTime, timeout and Polling

debounceTime emits the last value once the source goes quiet, throttleTime the first value of a window, auditTime the latest value at the end of a window; for polling, use exhaustMap or repeat({ delay }) instead of mergeMap so requests never overlap. In Bookstore we autosave a review draft, put timeout in the right place, poll an order's status only while the page is visible, and measure where the schedulers run in the event loop.

14 Nov 2026 22 min 11
RxJS Subject Types: Subject, BehaviorSubject, ReplaySubject, AsyncSubject and When to Use None of Them
Frontend PART 07

RxJS Subject Types: Subject, BehaviorSubject, ReplaySubject, AsyncSubject and When to Use None of Them

A late subscriber gets nothing from a Subject, the current value from a BehaviorSubject, the last N values from a ReplaySubject and the last value after complete from an AsyncSubject; in Angular 22, state lives in a signal and events in a private Subject. We compare the four types with real output, show the dead Subject, encapsulation with asObservable and the global event bus problem, and build Bookstore's cart with a signal and its toast with a Subject.

14 Nov 2026 15 min 13
Multicasting in RxJS: share, shareReplay, connectable and Sharing an HTTP Request
Frontend PART 08

Multicasting in RxJS: share, shareReplay, connectable and Sharing an HTTP Request

Angular's HttpClient returns a cold Observable; two async pipes send two requests, and sharing one request means storing the Observable in a field with share or shareReplay. We show with real measurements that share resets on completion, what shareReplay's refCount does, a cache with a lifetime, the fallback value cached by catchError and connectable, and share Bookstore's category list with a single request.

14 Nov 2026 14 min 13
Error Handling in RxJS: catchError, retry with Backoff, finalize and Catching Errors Without Killing the Stream
Frontend PART 09

Error Handling in RxJS: catchError, retry with Backoff, finalize and Catching Errors Without Killing the Stream

catchError does not catch and continue; it replaces the rest of the stream with the Observable you return, so a long-lived stream survives only if it sits inside switchMap, and retry belongs, with backoff and jitter, only on idempotent requests and 5xx or network errors. With real runs we show the double order, finalize, and in Angular HttpErrorResponse, ASP.NET Core ProblemDetails and how an interceptor and a component share the work.

14 Nov 2026 22 min 13
RxJS in Angular 22: HttpClient, Router and Forms Observables, Signal Interop and Subscription Management
Frontend PART 10

RxJS in Angular 22: HttpClient, Router and Forms Observables, Signal Interop and Subscription Management

In zoneless Angular 22 with OnPush by default, an Observable reaches the screen only through the async pipe, toSignal or a resource; time and event flow stay in RxJS, the state on screen in signals. We examine toSignal, toObservable, rxResource, httpResource and outputFromObservable with real measurements, write Bookstore's search box three ways, and show the takeUntilDestroyed errors and a leaking poll.

14 Nov 2026 15 min 13
Writing Custom RxJS Operators and Staying Readable: pipe Composition, Lint Rules and Debugging
Frontend PART 11

Writing Custom RxJS Operators and Staying Readable: pipe Composition, Lint Rules and Debugging

A custom operator is a function that takes an Observable and returns one; combining existing operators with pipe() is usually enough, and an operator written from scratch with new Observable must return its teardown. We turn Bookstore's search, retry-with-backoff and loading-state blocks into settledTerm, retryWithBackoff and loadingState, write debugTap from scratch, and catch mistakes such as nested subscribe automatically with eslint-plugin-rxjs-x.

14 Nov 2026 21 min 13
Testing RxJS: Marble Testing with TestScheduler, Fake Timers and Angular Services
Frontend PART 12

Testing RxJS: Marble Testing with TestScheduler, Fake Timers and Angular Services

Time-based RxJS code is tested inside TestScheduler.run() with virtual time and marble diagrams, without waiting on the real clock and checking the frame of every value. We test Bookstore's search flow, its retry with backoff and cancelled requests with marbles, the same tests with Vitest fake timers, and Angular services with HttpTestingController, and show the Promise and delay-outside-run() pitfalls with real output.

14 Nov 2026 18 min 13
Blog Map