Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NgRx Component Store
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Rainer Hahnekamp
July 20, 2022
Technology
130
1
Share
NgRx Component Store
Slides for my talk on NgRx Component Store
Rainer Hahnekamp
July 20, 2022
More Decks by Rainer Hahnekamp
See All by Rainer Hahnekamp
Vitest Highlights in Angular
rainerhahnekamp
0
260
From Hours to Minutes - An AI Case Study with Sheriff
rainerhahnekamp
0
25
RxJS, Signals, and Native Observables: Answering the Critical Questions
rainerhahnekamp
0
27
Zurück in den Browser – Das Comeback der Frontend-Tests
rainerhahnekamp
0
76
From Hours to Minutes: An AI Case Study with Sheriff
rainerhahnekamp
0
140
RxJS, Signals & Native Observables
rainerhahnekamp
0
130
The Road to Angular Today Milestones, Mistakes & Momentum
rainerhahnekamp
0
130
Next Generation Angular
rainerhahnekamp
0
50
2025-09-05_Hold_the_Line.pdf
rainerhahnekamp
0
250
Other Decks in Technology
See All in Technology
GitHub Actions侵害 — 相次ぐ事例を振り返り、次なる脅威に備える
flatt_security
12
7.2k
AIエージェント勉強会第3回 エージェンティックAIの時代がやってきた
ymiya55
0
200
Amazon Qはアマコネで頑張っています〜 Amazon Q in Connectについて〜
yama3133
1
170
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
3
2.1k
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
140
OpenClaw初心者向けセミナー / OpenClaw Beginner Seminar
cmhiranofumio
0
170
FASTでAIエージェントを作りまくろう!
yukiogawa
4
190
自分をひらくと次のチャレンジの敷居が下がる
sudoakiy
5
1.6k
Bref でサービスを運用している話
sgash708
0
220
Datadog で実現するセキュリティ対策 ~オブザーバビリティとセキュリティを 一緒にやると何がいいのか~
a2ush
0
180
Embeddings : Symfony AI en pratique
lyrixx
0
440
How to install a gem
indirect
0
2k
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
260
AI: The stuff that nobody shows you
jnunemaker
PRO
4
500
We Are The Robots
honzajavorek
0
210
How to build a perfect <img>
jonoalderson
1
5.3k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
180
Being A Developer After 40
akosma
91
590k
Deep Space Network (abreviated)
tonyrice
0
99
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
700
Fireside Chat
paigeccino
42
3.9k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
780
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
400
Transcript
NgRx Component Store NgRx Component Store Rainer Hahnekamp 20.7.2022
About Me... • Rainer Hahnekamp ANGULARarchitects.io • Trainings and Consulting
@RainerHahnekamp Professional NgRx https://www.ng-news.com https://www.youtube.com /c/RainerHahnekamp
Agenda • NgRx Family • Theory • Selectors • Actions
• Effects • Miscellaneous
NgRx Family Store Effects Entity Data Router Store Store Devtools
Schematics ESLint Plugin Component Store Component
Main facts • (Little) sibling to @ngrx/store • Local /
component state management • State vanishes with component (by default) • Push-based • All logic included in single service
Use cases • Complicated, local state logic • Multiple instances
of same components • Different static logic (Decoupling, Shared) • ~Simplified, global state
API ComponentStore SideEffects Read Write select(): Observable patchState() setState() updater()
// like reducer effect()
Defining the state export interface HolidaysState { holidays: Holiday[]; favouriteIds:
number[]; } @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { constructor(private httpClient: HttpClient, private config: Configuration) { super({ holidays: [], favouriteIds: [] }); } }
Selectors export interface HolidaysState { holidays: Holiday[]; favouriteIds: number[]; }
@Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { constructor(private httpClient: HttpClient, private config: Configuration) { super({ holidays: [], favouriteIds: [] }); } readonly holidays$ = this.select(({ holidays, favouriteIds }) => holidays.map((holiday) => ({ ...holiday, isFavourite: favouriteIds.includes(holiday.id), })) ); }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { } }
Actions @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { // ...
addFavourite(holidayId: number) { this.patchState((state) => ({ favouriteIds: [...state.favouriteIds, holidayId], })); } removeFavourite(holidayId: number) { this.patchState((state) => ({ favouriteIds: state.favouriteIds.filter((id) => id !== holidayId), })); } }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { } addFavourite(id: number) { this.holidaysStore.addFavourite(id); } removeFavourite(id: number) { this.holidaysStore.removeFavourite(id); } }
Effects @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { // ...
readonly load = this.effect((i$: Observable<void>) => { return i$.pipe( switchMap(() => this.httpClient.get<Holiday[]>(this.#baseUrl).pipe( tapResponse((holidays) => { const finalHolidays = holidays.map((holiday) => ({ ...holiday, imageUrl: `${this.config.baseUrl}${holiday.imageUrl}`, })); this.#setHolidays(finalHolidays); }, console.error) ) ) ); }); #setHolidays = (holidays: Holiday[]) => this.patchState({ holidays }); }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { this.holidaysStore.load(); } addFavourite(id: number) { this.holidaysStore.addFavourite(id); } removeFavourite(id: number) { this.holidaysStore.removeFavourite(id); } }
Comparison to store • Same reactive behaviour • No devtools
• Scalability issues • Simpler • Nice goodies ◦ patchState ◦ Debounced selectors
Also keep in mind • Disposing of resources is built-in
• Combination with @ngrx/store possible • Can also manage global state ◦ via {providedIn: 'root'}
When to use? • Instead of services based on BehaviorSubject
• Non-global state • Early phases of application development
Alternatives Elf @rx-angular/state
Summary • Simple State Management • Reactive Behaviour • Easy
to upgrade to NgRx Store later
Further Reading/Watching • Original Design Document ◦ https://hackmd.io/zLKrFIadTMS2T6zCYGyHew?view • Official
Documentation ◦ https://ngrx.io/guide/component-store • Alex Okrushko on Component Store ◦ https://www.youtube.com/watch?v=v5WSUE1_YHM