Как установить initialState в @ngrx/core с промисом от indexedDB

Я хотел установить начальное состояние в ngrx с помощью пакета idb, который использует обещание для получения данных, но каждый раз, когда я пытался его настроить, я получаю сообщение об ошибке. Я читал, что @ngrx является синхронным, значит ли это, что он не работает с промисами. Различные методы, которые я пробовал:

это мой метод-оболочка для idb, который загружает данные, он отлично работает

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

и различные методы, которые я пробовал, устанавливают начальное состояние

метод: 1

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

метод: 2

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

метод: 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);
  };

}

Состояние инициализации устанавливается на это

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

и я получаю эту ошибку

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)

*******Обновлять*******

Я понял это сейчас, поскольку ди Зг указал, что каждое состояние может иметь функцию инициализации в своих эффектах, которая будет запускаться по мере их загрузки, я сначала подумал, что это глобальное одноразовое событие. Вот один, который я использую для состояния аутентификации

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

person ramon22    schedule 09.12.2017    source источник


Ответы (1)


В эффектах есть действие init, которое срабатывает при запуске эффектов. Там вы можете отправить свое действие, получить данные и заполнить начальное состояние. Проверьте раздел Init Action здесь: https://github.com/ngrx/platform/blob/master/MIGRATION.md

person dee zg    schedule 09.12.2017
comment
Не знал, что init существует, спасибо, но в своем примере они используют defer ex: init$: Observable‹Action› = defer(() =› of(new RootInit())); как я могу вызвать обещание для отправки в качестве полезной нагрузки с помощью RootInit. - person ramon22; 09.12.2017