Ждать состояния в резольвере (ngrx)

Сейчас у меня есть резолвер, вызывающий стандартную службу и возвращающий Observable:

return this.someService.getData()
      .map(data=> data.json())

Я хочу заменить его эффектами ngrx и сохранить. Когда решатель запускается, я хочу отправить requestAction, перехваченный эффектом, который отправляет http запрос. Как только данные возвращаются, я отправляю dataReceivedAction с данными в качестве полезной нагрузки.

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

return Observable.combineLatest(
      Observable.of(
        this.store.dispatch(new requestAction())
      ),
      this.store.select(store => store.dataIWaitFor),
      (dispatchedAction, dataArrived) => dataArrived
    )
      .skip(1)

это не работает, я имею в виду, что распознаватель не отображает компонент, но когда в конце каждого из этих возвращаемых Observables я добавляю

.do(data => console.log(data))

одни и те же данные регистрируются. Что я делаю не так?

2 ответа

Вы можете сделать что-то вроде этого

@Injectable()
export class SomeGuard implements CanActivate {
constructor(private store: Store<AppState>) {}

waitForDataToLoad(): Observable<Something> {
    return this.store.select(state => state.something)
        .filter(something => something && !something.empty);
}

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
    this.store.dispatch({type: LOAD_something});

    return this.waitForDataToLoad()
        .switchMap(() => {
            return Observable.of(true);
        });
    }
}
}

Я попытался реализовать ваше решение в распознавателе вместо охранника, он хорошо заполняет мой магазин ngrx, но навигация не выполняется, я застрял на странице, откуда я вызываю маршрут с распознавателем. Также в магазине мы можем видеть данные и router-store/requested и router-store/navigation, но не router-store/navigated, ни router-store/cancel, например, когда охранник блокирует навигацию. Знаете, чего мне не хватает и почему ничего не происходит с навигацией? Я использовал преобразователь в своем маршруте следующим образом:

        {
    path: "params/users",
    canActivate: [IsAdminGuard],
    component: UsersComponent,
    resolve: { usersLoaded: UsersResolver }
  }

А вот и резольвер, почти как у вашей гвардии:

      @Injectable()
export class UsersResolver implements Resolve<boolean> {

  constructor(private store: Store<appState>) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {        
  // API calls with ngrx effect 
  this.store.dispatch(usersActions.GET_USERS_TRY());

  // Select users in store, switchMap(true) if array not empty
  return this.store.pipe(
    select(UsersSelectors.allUsers),
    filter((allUsers: users[]) => allUsers.length > 0),
    switchMap((allUsers: users[]) => return of(true))
  );
  }
}
Другие вопросы по тегам