Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Modern State Management in Angular: 3+n Flavors...
Search
Manfred Steyer
PRO
April 10, 2024
Programming
290
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Modern State Management in Angular: 3+n Flavors of the Signal Store @ijs London 2024
Manfred Steyer
PRO
April 10, 2024
More Decks by Manfred Steyer
See All by Manfred Steyer
Human in the Loop Beyond Approval: Toward True Collaboration @FrontMania 2026 in Utrecht
manfredsteyer
PRO
0
36
Agentic UI: Where the Agent meets the User @FrontMania 2026 in Utrecht
manfredsteyer
PRO
0
31
A2UI as an Architecture Question: Agentic UI Between AI Freedom and Control
manfredsteyer
PRO
0
85
AI-Ready Angular Architectures Architecture as Executable Contract
manfredsteyer
PRO
0
230
Nostalgia Meets Technology: Super Mario with TypeScript @BASTA 2026 in Mainz, Germany
manfredsteyer
PRO
0
44
Beyond Chatbots: Agentic UI with Open Standards @AGNTcon 2026 in Amsterdam
manfredsteyer
PRO
0
140
Next-Level Frontends: Agentic Web UIs Under the Hood
manfredsteyer
PRO
0
100
Agentic UI with Open Standards @ngGraz Sep 2026
manfredsteyer
PRO
0
110
Agentic UI with Open Standards @GDG Salzburg, Bgl & Prishtina
manfredsteyer
PRO
0
94
Other Decks in Programming
See All in Programming
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
270
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
160
JRuby: Past, Present, and Future
headius
0
220
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.2k
パーソナライズPodcastを作った話
repunit11
0
120
R8 の設定見直しでアプリサイズ削減
andpad
0
190
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
140
FreeBSDでZabbixを動かす
kenkino
0
360
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2k
dotNET_vulnclicker_intro.pdf
deka_morita
0
110
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
780
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
390
Featured
See All Featured
Designing Experiences People Love
moore
143
24k
GitHub's CSS Performance
jonrohan
1033
470k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
450
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
The Cost Of JavaScript in 2023
addyosmani
55
10k
A designer walks into a library…
pauljervisheath
211
25k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
Ruling the World: When Life Gets Gamed
codingconduct
0
390
Producing Creativity
orderedlist
PRO
348
41k
Transcript
@ManfredSteyer ManfredSteyer Modern State Management in Angular 3+n Flavors of
the Signal Store
@ManfredSteyer Signal as Producer 4711 Consumer read set notify 4712
@ManfredSteyer Signal Eventually Zone-less!
@ManfredSteyer flights = signal<Flight[]>([]); const flights = await this.flightService.findAsPromise(from, to);
this.flights.set(flights); <div *ngFor="let f of flights()"> <flight-card [item]="f" /> </div>
@ManfredSteyer from = signal('Paris'); to = signal('London'); flightRoute = computed(()
=> this.from() + ' to ' + this.to()); constructor() { effect(() => { console.log('from', this.from()); console.log('to', this.to()); }); }
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Component Store "Intention" Signals sync/ async computed(…) computed(…)
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Manfred Steyer
@ManfredSteyer
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { private
state = signalState({ from: 'Paris', to: 'London', flights: [] as Flight[], basket: {} as Record<number, boolean>, }); readonly flights = this.state.flights; readonly from = this.state.from; […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
readonly selected = computed( () => this.flights().filter((f) => this.basket()[f.id]) ); […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
updateCriteria(from: string, to: string): void { patchState(this.state, { from, to }) } […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
updateCriteria(from: string, to: string): void { patchState(this.state, (state) => ({ from: state.to, to: state.from })); } […] }
@ManfredSteyer
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
[…] );
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
withState({ from: 'Paris', to: 'London', […] }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
withState({ from: 'Paris', to: 'London', […] }), withComputed(([…]) => ({ […] })), withMethods(([…]) => ({ })), withHooks({ […] }) );
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe([…])) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe([…])) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe( filter(c => c.from.length >= 3 && c.to.length >= 3), debounceTime(300), switchMap((c) => flightService.find(c.from, c.to)), tap(flights => patchState(state, { flights })) )) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe( filter(c => c.from.length >= 3 && c.to.length >= 3), debounceTime(300), switchMap((c) => flightService.find(c.from, c.to)), tap(flights => patchState(state, { flights })) )) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withHooks({ onInit({ connectCriteria,
criteria }) { connectCriteria(criteria); }, }), ); takes: Signal<T>, Observable<T>, T
@ManfredSteyer
@ManfredSteyer const BookingStore = signalStore( withEntities<FlightState>() );
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Michael Egger-Zikes Rainer Hahnekamp Manfred Steyer
@ManfredSteyer Free eBook (6th Edition) ANGULARarchitects.io/book 20 Chapters 4 new
Signal Store Chapters
@ManfredSteyer Signals: Future of CD Take Care of Data Flow
Stores are the Missing Link Signal Store Lightweight Highly Extensible
@ManfredSteyer
@ManfredSteyer d Slides & Examples Remote Company Workshops and Consulting
http://angulararchitects.io