How to set initialState in @ngrx/core with a promise from indexedDB

那年仲夏 提交于 2020-01-02 18:04:31

问题


I wanted to set the initial state in ngrx using the idb package which uses promise to fetch data, but am getting an error every time I tried to set it up. I read that @ngrx is synchronous does that mean it does not work with promises. The different methods I tried:

this is my wrapper method for idb that loads in the data it works fine

export function getInitialState(): Promise<any> {
  return StorageService.dB.loadInitialState('app-state');
}

and the different methods I tried set the initial state

method: 1

StoreModule.forRoot(reducers, {initialState: getInitialState})

method: 2

 import { INITIAL_STATE } from '@ngrx/store';
{ provide: INITIAL_STATE, useFactory: getInitialState }

method: 3

export function logger(reducer: ActionReducer<State>): ActionReducer<State> {
  return function (state: State, action: any): State {
   if(action.type === '@ngrx/store/init') {

   }
    return reducer(state, action);
  };

}

The init state gets set to this

ZoneAwarePromise {__zone_symbol__state: null, __zone_symbol__value: Array(0)}

and I get this error

ERROR TypeError: Cannot assign to read only property '__zone_symbol__state' of object '[object Object]'
    at resolvePromise (zone.js:810)
    at eval (zone.js:876)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4747)
    at ZoneDelegate.invokeTask (zone.js:424)
    at Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at ZoneTask.invokeTask [as invoke] (zone.js:503)
    at invokeTask (zone.js:1540)
    at IDBRequest.globalZoneAwareCallback (zone.js:1566)

*******Update*******

I got it now as dee zg pointed out every state can have an init function in their effects that will be fired as they are loaded, I thought it was a global one time event at first. Here is one I use for Auth state

 @Effect()
  init$: Observable<Action> = defer(() => {
    return from(StorageService.readItem('app', Auth.AUTH_KEY)).pipe(
       map((data: any) => {
        return new Auth.AuthInit(data.state);
      })
    );
  });

回答1:


There is an init action in effects which fires when effects get ran. There you can dispatch your action, get data and fill initial state. Check Init Action section here: https://github.com/ngrx/platform/blob/master/MIGRATION.md



来源:https://stackoverflow.com/questions/47725517/how-to-set-initialstate-in-ngrx-core-with-a-promise-from-indexeddb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!