#angular #ngrx #ngrx-effects
#angular #ngrx #ngrx-эффекты
Вопрос:
Что я делаю
У меня есть приложение Angular, и я внедряю NGRX 10 для управления информацией об учетной записи после входа в систему. Итак, я выполнил действия для входа в систему, которые вызываются, когда пользователь выполняет вход в систему или когда загружает приложение и загружает сеанс с сервера.
Вот как я реализую свой эффект входа в систему
LogIn$ = createEffect(
() => this.actions$.pipe(
ofType(UserActions.logInUser),
switchMap(( action ) => {
console.log('login');
return this.backendService.login(action.credentials, action.remember).pipe(
mergeMap(data => [
UserActions.logInUserSuccess(data),
UserActions.saveOAuthInCookie(data)
]),
catchError( error => of(UserActions.loginUserFail(error)))
);
})
), { dispatch: true }
);
Мне нужно быть уверенным, что информация об учетной записи уже загружена с сервера, когда я получаю доступ к закрытому разделу страницы с ранее открытым сеансом.
Затем я пытаюсь реализовать что-то вроде следующего кода в моем модуле приложения:
export function initApplication(store: Store<IState>): Function {
return () => new Promise((resolve, reject) => {
store.dispatch(StartAppInitializer({}));
store.dispatch(loadOAuthFromCookie({}));
store.select((state) => state.user)
.pipe(
filter(user => ((user.oAuthToken amp;amp; user.oAuthToken.length > 0 amp;amp;
(user.account amp;amp; user.account.email amp;amp; user.account.email.length > 0) ) ||
(!user.oAuthToken || user.oAuthToken.length === 0))),
take(1)
).subscribe((account) => {
store.dispatch(FinishAppInitializer({}));
resolve(false);
});
});
}
и в моем классе эффектов реализован OnRunEffects
и этот код:
ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification> {
return this.actions$.pipe(
ofType('LOGGED_IN'),
exhaustMap(() =>
resolvedEffects$.pipe(
takeUntil(this.actions$.pipe(ofType('LOGGED_OUT')))
)
)
);
}
Это меняет его, предполагая, что он будет ждать до вызова приложения FinishAppInitializer
.
Чего я хочу
Я хочу остановить загрузку приложения до тех пор, пока NGRX не получит информацию об учетной записи с сервера
Что я получаю
До того, как я внедрил ngrxOnRunEffects в свой класс эффектов, эффекты, которые у меня есть, работают, но после того, как я внедрил ngrxOnRunEffects в свой класс эффектов, другие эффекты перестают отправлять другие действия.
Это некоторое изображение для ссылки на то, что происходит при входе в систему:
Изображение перед I реализует ngrxOnRunEffects
Изображение после I реализует ngrxOnRunEffects
Решение, которое я нашел
Сначала я изменил это:
{
provide: APP_INITIALIZER,
useFactory: () => initApplication,
multi: true,
deps: [[new Inject(Store)]]
},
Для этого:
{
provide: APP_INITIALIZER,
useFactory: initApplication,
multi: true,
deps: [[new Inject(Store)]]
},
Это изменение приводит к остановке приложения до тех пор, пока не будет выполнено обещание.
И, во-вторых, я переместил метод ngrxOnRunEffects в другой класс, это решило проблему, заключающуюся в том, что никакие другие эффекты не вызывались.