Natali Gamboa
Natali Gamboa

Reputation: 75

Persist data with redux in angular

I'm using redux with angular, but when I reload the page I lose the store, how can I persist this data when the page is reloaded?

Upvotes: 1

Views: 2107

Answers (2)

Abdullah Abid
Abdullah Abid

Reputation: 1661

I Understand it's an old question but Since this has wasted a lot of my time so i'm going to leave this here incase someone is looking for it.

Notice: I am using @angular-redux/store (from here) with this solution

store.ts

Inside the store create a function that loads the state from the localStorage if it exists and a Custom middleware that saves the state into the localStorage whenever an action is dispatched

import {
  IAuthInterface,
  AUTH_INITIAL_STATE, 
  authReducer,  
} from './app/reducers/authReducer';
import { combineReducers } from 'redux';
export interface IAppState {
  auth: IAuthInterface;
}

export const INITIAL_STATE: IAppState = {
  auth: AUTH_INITIAL_STATE
};

export const rootReducer = combineReducers({
  auth: authReducer,
});

// Get Value from LocalStorage variable if it exists  
export const loadState = () => {
  try {
    const serializedState = localStorage.getItem('state');
    if (serializedState === null) {
      return undefined;
    }
    return JSON.parse(serializedState);
  } catch (err) {
    return undefined;
  }
}; 
// Create Middleware to Save State when an action is dispatched
export const PersistMiddleware = ({ getState }) => (next) => async (action) => {
  setTimeout(  () => { //used to simulate async action
      const serializedState = JSON.stringify(getState());
      localStorage.setItem('state', serializedState);
    }, 0);
  next(action);
}


const State = loadState();
export const persistedState = State ? State : INITIAL_STATE;

app.module.ts

Inside the app module Make the neccessary Imports

 import {
      NgRedux,
      NgReduxModule,
      DevToolsExtension,
     } from '@angular-redux/store';
 import { 
      IAppState,
      rootReducer,
      persistedState,
      PersistMiddleware
     } from   'src/store'; //store.ts file

and pass your custom middleware and state to the store

export class AppModule { 
  constructor(ngRedux: NgRedux<IAppState>, devtools: DevToolsExtension) {
    ngRedux.configureStore(
      rootReducer,
      persistedState,
      [PersistMiddleware],
      [devtools.enhancer()]
    );
  }
}

sources used:

For loadState Method

For Custom Middleware

Also For Custom Middleware

Upvotes: 2

yaswanthkoneri
yaswanthkoneri

Reputation: 418

You can use this module to implement redux persist state https://github.com/btroncone/ngrx-store-localstorage

Implementation

npm install ngrx-store-localstorage --save

UPDATE FOR NGRX 4

Wrap localStorageSync in an exported function. Include in your meta-reducers array in StoreModule.forRoot.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule, ActionReducerMap, ActionReducer, MetaReducer } from '@ngrx/store';
import { localStorageSync } from 'ngrx-store-localstorage';
import { reducers } from './reducers';


const reducers: ActionReducerMap<IState> = {todos, visibilityFilter};

export function localStorageSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> {
  return localStorageSync({keys: ['todos']})(reducer);
}
const metaReducers: Array<MetaReducer<any, any>> = [localStorageSyncReducer];

@NgModule({
  imports: [
    BrowserModule,
    StoreModule.forRoot(
        reducers,
        {metaReducers}
    )
  ]
})
export class MyAppModule {}

Upvotes: 1

Related Questions