angularreduxangular-redux

How to use redux-state-sync middleware with angular-redux?


I have existing code where I have configured the store in AppModule constructor:

export class AppModule {

  constructor(ngRedux: NgRedux<IApplicationState>) {

  // Tell @angular-redux/store about our rootReducer and our initial state.
  // It will use this to create a redux store for us and wire up all the
  // events.
  ngRedux.configureStore(rootReducer, INITIAL_STATE);
}

This is pretty much how the documentation tells to use it.

Now I'm trying to use redux-state-sync with my store. However the redux-state-sync documentation's example instructs me to use createStore instead of configureStore:

import { createStore, applyMiddleware } from 'redux'
import { createStateSyncMiddleware } from 'redux-state-sync';

const config = {
  // TOGGLE_TODO will not be triggered in other tabs
  blacklist: ['TOGGLE_TODO'],
}
const middlewares = [
  createStateSyncMiddleware(config),
];
ā€Š
const store = createStore(rootReducer, {}, applyMiddleware(...middlewares));

If I try to add the middleware to configureStore:

ngRedux.configureStore(rootReducer, INITIAL_STATE, applyMiddleware(...middlewares));

I get error:

ERROR in src/app/app.module.ts(51,56): error TS2345: Argument of type 'StoreEnhancer<{ dispatch: {}; }, {}>' is not assignable to parameter of type 'Middleware<{}, any, Dispatch>[]'. Type 'StoreEnhancer<{ dispatch: {}; }, {}>' is missing the following properties from type 'Middleware<{}, any, Dispatch>[]': pop, push, concat, join, and 25 more.

How can I use redux-state-sync with angular-redux?

Thanks!

EDIT:

I can do like this:

const config = {
  blacklist: ['TOGGLE_TODO'],
}
const middlewares : Middleware[] = [
  createStateSyncMiddleware(config),
];
ngRedux.configureStore(rootReducer, INITIAL_STATE, middlewares);

but it seems like the state changes are not synced to other tabs.


Solution

  • Unfortunately I didn't get this to work properly on broadcast-channel (see Why redux @select does not work even though the state is changed when using redux-state-sync?) so here it is with localstorage.

    app.module.ts

    import { createStateSyncMiddleware, initStateWithPrevTab } from 'redux-state-sync';
    import { Store, createStore, applyMiddleware } from 'redux';
    
    export const store: Store<IApplicationState> = createStore(
      rootReducer,
      applyMiddleware(createStateSyncMiddleware({ broadcastChannelOption: { type: 'localstorage' } })
    );
    
    export class AppModule {
      constructor(ngRedux: NgRedux<any>) {
        initStateWithPrevTab(store);
        ngRedux.provideStore(store);
      }
     }
    

    store/index.ts

    import { combineReducers  } from 'redux'
    import { ILoginState, loginReducer } from './login'
    import { withReduxStateSync } from 'redux-state-sync'
    
    export interface IApplicationState {
      login: ILoginState;
    }
    
    export const INITIAL_STATE : IApplicationState = {
       login : { isLoggedIn: false, tokenInfo : null } 
    }
    
    const appReducer = combineReducers<IApplicationState>({
      login: loginReducer
    })
    
    export const rootReducer = withReduxStateSync(appReducer);