Slide 1

Slide 1 text

Hold the Line! SignalStore aligned with Angular’s latest Angular Architects RainerHahnekamp

Slide 2

Slide 2 text

About Me... https://www.youtube.com/ @RainerHahnekamp https://www.ng-news.com https://github.com/softarc-consulting/sheriff ● Rainer Hahnekamp ANGULARarchitects.io NgRx Team (Trusted Collaborator) ● Developer / Trainer / Speaker @RainerHahnekamp Workshops NgRx • Testing • Spring • Quality

Slide 3

Slide 3 text

Agenda ● The Importance of State ● Why SignalStore ● How do we work? ● Where are we? ● What comes next?

Slide 4

Slide 4 text

I don't need State! (traumatized devs)

Slide 5

Slide 5 text

State is the essence of SPAs

Slide 6

Slide 6 text

The Angular Way From Events to State

Slide 7

Slide 7 text

a b c d e State Events (Observables, Callbacks) "Event-based" Change Detection / Synchronization (zone.js) No State-Changing Events

Slide 8

Slide 8 text

a b c d e State (Signals) Events (Observables, Callbacks) "State-based" Change Detection / Synchronization (Signals)

Slide 9

Slide 9 text

Angular's "State Management" Stable signal() computed() effect() afterRenderEffect() linkedSignal() Experimental resource()

Slide 10

Slide 10 text

You need to manage State, but do you need an Explicit Library?

Slide 11

Slide 11 text

RainerHahnekamp Benefits SignalStore Extensible Simple Standardized Utility Functions Always based on Angular's Signals

Slide 12

Slide 12 text

A Comparison: State & Slices @Injectable({ providedIn: 'root' }) export class HolidaysStore { // State readonly #state = signal({ holidays: [] as Holiday[], favouriteIds: [] as number[], filter: { query: '', type: 0 }, }); // Slices holidays = computed(() => this.#state().holidays); favouriteIds = computed(() => this.#state().favouriteIds); filter = computed(() => this.#state().filter); } export const HolidayStore = signalStore( { providedIn: 'root' }, withState({ holidays: [] as Holiday[], favouriteIds: [] as number[], filter: { query: '', type: 0 }, }) );

Slide 13

Slide 13 text

A Comparison: Computeds export class HolidaysStore { // Computed holidaysCount = computed(() => this.#state().holidays.length); } export const HolidayStore = signalStore( withComputed(({ holidays }) => ({ holidaysCount: () => holidays().length, })), );

Slide 14

Slide 14 text

A Comparison: Methods export class HolidaysStore { // Methods readonly #httpClient = inject(HttpClient); async load() { const holidays = await lastValueFrom( this.#httpClient.get('/holiday'), ); this.#state.update((state) => ({ ...state, holidays })); } } export const HolidayStore = signalStore( withMethods((store, httpClient = inject(HttpClient)) => ({ async load() { const holidays = await lastValueFrom( httpClient.get('/holiday'), ); patchState(store, { holidays }); }, })) );

Slide 15

Slide 15 text

Hold the Line ● Built on top of Angular Signals ○ Not create a parallel universe ● Work closely with the Angular Team ○ No Plan for a full State Management ● Adapt whenever necessary ● Don't break things ○ Careful Design (takes longer) ○ Migrations ○ Don't provide too much

Slide 16

Slide 16 text

● Stable Version ● Features for "larger" Stores ○ Protected State ○ Encapsulation ○ Overriding Warning Version 18

Slide 17

Slide 17 text

Version 19 ● signalMethod ○ RxJS-less connector ○ Explicit Tracking ● withProps ○ Generic Feature for adding non-standardized elements ○ Not a state, method or computed ● withFeature ○ For Library Authors ○ Allows Custom Features to access the calling Store ● Events Plugin ○ Optionals ○ Redux for the SignalStore ○ Minor Differences to @ngrx/store ○ "One size fits all" Solution

Slide 18

Slide 18 text

Version 20 ● Support for linkedSignal ○ Via withLinkedState ○ Per Slice (not the whole State) ○ Also supports user-defined Signals ● Support for resource/rxResource/httpResource ○ PR available but on hold ○ resource needs to be developer preview ○ Implementation available via ngrx-toolkit

Slide 19

Slide 19 text

Where are we going?

Slide 20

Slide 20 text

withResource() ● Writable only internally, read only to the outside ● SignalStore as Resource ● Named Resources ○ Along mapper functions ● Further Investigation for withEntities integration

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

NgRx Toolkit Mutations ● Resource for "Changing Data" ● Potential upcoming feature for Angular ● Design Consultations with ○ Alex Rickabaugh (Angular Core) ○ Marko Staminirovic (NgRx) ● "Mutation Mindset" ● Usable outside the SignalStore

Slide 23

Slide 23 text

Upcoming AngularArchitects NgRx Workshop https://www.angulararchitects.io/training/ professional-ngrx-advanced-state-management-workshop/