Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Choosing the Right State Tool and the Evolution of Angular State: From BehaviorSubject to Signal Store
The right state tool follows from the kind of state: derived values use computed, server state a resource, shareable state the URL, and client state, depending on its scope, a signal, a signal service, Signal Store, the Events plugin or the classic Store. We sum up the choices for Bookstore's nine features, the bundle cost measured from the snapshots, the rules for dependencies between stores, NgRx Toolkit withDevtools, and the version-checked evolution from BehaviorSubject to Signal Store.
Testing State in Angular: Signal Services, Signal Store and NgRx Store Tests
State code is tested through its public API: a Signal Store is obtained from TestBed like a service, effects are run with TestBed.tick(), HTTP is controlled with HttpTestingController and time with Vitest fake timers, while the classic Store's reducers, selectors and functional effects are tested as pure functions. We write 19 Vitest tests for Bookstore's cart, search, checkout and back office state and show with real output that an effect never runs when TestBed.tick() is forgotten.
The NgRx Signal Store Events Plugin: Event-Driven State with event, eventGroup, withReducer and withEventHandlers
The Events plugin separates "what happened" from "how state changes" in flows where several stores react to the same occurrence: a component dispatches an event, each store changes its own state with withReducer, and withEventHandlers runs side effects. In Bookstore's checkout a single orderPlaced event empties the cart, records the order and shows a notification; we compare it with a method-based version and show with real output how a store that does not exist yet misses the event.
Advanced Signal Store: withEntities, rxMethod, signalMethod, withLinkedState and Custom Store Features
The advanced parts of Signal Store take repeated work out of your stores: withEntities manages collections with updaters, rxMethod handles cancellable async work with RxJS, signalMethod does the same without RxJS, and custom features plug into any store. We move Bookstore's cart to entities, build quick search with rxMethod, add withRequestStatus() and a typed log feature using SignalStoreFeatureType, and show with real output how an error without tapResponse ends the stream.
Getting Started with NgRx Signal Store: signalStore, withState, withComputed, withMethods and patchState
NgRx Signal Store provides the parts of a hand-written signal store as ready-made features: withState for state signals, withComputed for derived values, withMethods and patchState for immutable updates, withProps and withHooks for dependencies and lifecycle. We convert Bookstore's cart and checkout without changing component code and show with real output protected state, private members, NgRx 22's union DeepSignal, the Map pitfall and a cart lost when the persisted shape changes.