From: Kai Moritz Date: Mon, 15 Sep 2025 21:45:44 +0000 (+0200) Subject: feature: persist `username` to and rehydrate it from local-storage X-Git-Url: https://juplo.de/gitweb/?a=commitdiff_plain;h=14fbcc324e8f67bf78bbcc2186e8884779038ef4;p=demos%2Fangular%2Fstored-login feature: persist `username` to and rehydrate it from local-storage --- diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 115142e..288833e 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -6,10 +6,11 @@ import { provideStore } from '@ngrx/store'; import { provideEffects } from '@ngrx/effects'; import { loginReducers } from './store/login.reducers'; import { LoginEffects } from './store/login.effects'; +import { loginMetaReducer } from './store/login.metareducer'; export const appConfig: ApplicationConfig = { providers: [ - provideStore({ login : loginReducers }), + provideStore({ login : loginReducers }, { metaReducers: [loginMetaReducer] }), provideEffects([LoginEffects]), provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) diff --git a/src/app/store/login.metareducer.ts b/src/app/store/login.metareducer.ts new file mode 100644 index 0000000..5a03f6e --- /dev/null +++ b/src/app/store/login.metareducer.ts @@ -0,0 +1,44 @@ +import { Action, ActionReducer, INIT, UPDATE } from '@ngrx/store'; +import { State } from './login.reducers'; + +const STORAGE_KEY = 'login'; + +function saveStateSlice(state: State) { + const { username } = state; + return { username }; +} + +export function loginMetaReducer>(reducer: ActionReducer): ActionReducer { + return (state, action) => { + // 1) Rehydrate beim App-Start + if (action.type === INIT || action.type === UPDATE) { + const storedState = localStorage.getItem(STORAGE_KEY); + if (storedState) { + try { + const parsed = JSON.parse(storedState) as Partial; + // vorhandenen State um gespeicherte Felder erweitern + return { + ...state, + login: { + ...(state as any)?.login, + ...parsed + } + }; + } catch { + localStorage.removeItem(STORAGE_KEY); + } + } + } + + // 2) Normal Reducer ausführen + const nextState : any = reducer(state, action); + + // 3) Nur login-Slice persistieren + const loginSlice = (nextState as any)?.login as State; + if (loginSlice) { + localStorage.setItem(STORAGE_KEY, JSON.stringify(saveStateSlice(loginSlice))); + } + + return nextState; + }; +}