Feat/Modernize budget viewer state with signals#182
Open
CarolGitonga wants to merge 5 commits intoitalanta:mainfrom
Open
Feat/Modernize budget viewer state with signals#182CarolGitonga wants to merge 5 commits intoitalanta:mainfrom
CarolGitonga wants to merge 5 commits intoitalanta:mainfrom
Conversation
Author
|
Refactored SelectBudget and BudgetTable to Angular Signals |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For this refactor, I migrated the budget selection feature from a classic Angular/RxJS pattern to a modern Angular Signals–based architecture. The goal was to make the component tree more declarative, predictable, and fine-grained in how it responds to data updates.
My approach followed four steps required by the assignment:
Replaced constructor-based dependency injection with the modern inject() API to support tree-shakable, functional Angular architecture.
Converted RxJS Observables (overview$, sharedBudgets$, allBudgets$) into Signals using toSignal().
Replaced pipe/subscribe-based logic with computed() for derived state and effect() for component side effects.
Updated the parent template to pass signal values instead of Observables to the child component, and refactored the child to accept standard Inputs.
This resulted in a clean, reactive component with minimal imperative logic and no manual subscriptions.
Previous approach (RxJS + subscribe/async pipe)
Component lifecycle managed with OnInit
Manual wiring of streams using combineLatest, map, pipe
Imperative subscribe() for side effects
Parent passed Observables to child components
Multiple change detection cycles triggered through async pipes
Signals-based approach
No lifecycle hooks required; Signals react immediately
computed() expresses relationships declaratively instead of manually mapping streams
effect() replaces imperative subscribe() and handles side effects cleanly
Parent passes plain values (or signal-derived values) to child inputs
Fine-grained reactivity reduces unnecessary template re-renders
State is synchronous and always available
Signals lead to simpler codepaths, better readability, and more predictable UI behavior, especially for large or frequently changing datasets.
Observables
Represent asynchronous streams that can emit multiple values over time
Excellent for HTTP calls, event streams, and complex async operations
Require subscription management (either manually or via async pipes)
Push-based: values are emitted to the consumer
Signals
Hold synchronous state with a current value always available
Not inherently asynchronous (but can wrap async streams with toSignal())
Change detection is fine-grained and dependency-tracked
Pull-based: templates/functions call the signal to read its current value
Work extremely well for UI state, presentation logic, and computed derivations
In this assignment:
I continued to use Observables for the store-level data layer (as intended in the codebase), but converted them into Signals at the presentation layer for optimal UI performance and clarity.
I have worked with React Hooks (useState/useEffect/useMemo) and Vue’s Composition API. Angular Signals bring Angular much closer to these modern paradigms:
Like React, computed() resembles useMemo, and effect() resembles useEffect without dependency arrays.
Like Vue, Signals provide fine-grained dependency tracking and predictable state access.
Unlike React or Vue, Signals integrate directly with Angular’s underlying change detection system, eliminating the need for zones and allowing future zoneless applications.
“This refactor uses Angular Signals (computed, effect, toSignal) which require Angular 16+.