#angular #store #ngrx
#angular #Магазин #ngrx
Вопрос:
Краткое изложение того, что я хочу
- Вызовите api 1
- Вызовите api 2
- Подождите, пока эти данные не будут сохранены в
store
- Получите эти данные через на уровне
effect
Описание
Что я хотел бы сделать, это просто подождать, пока некоторые действия не будут должным образом завершены и сохранены в хранилище. А затем запустите следующий.
Например,
@Effect()
getData1$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.getData1Action),
switchMap(action => { // Simply call an api and save data in the store by calling GetData1Success.
this.httpClient.get(...)
.pipe(
map((result) => new GetData1Success(result))
)
})
);
@Effect()
someEffect$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.UserLogIn),
flatMap(_ => { // get first data
this.store.dispatch(new getData1());
return of(_);
}),
flatMap(_ => { // get second data
this.store.dispatch(new getData2());
return of(_);
}),
switchMap(action => { // run final action
return [new finalAction()];
}),
catchError(() => of(new finalActionFailure()))
);
И затем finalAction()
выполняется,
@Effect()
finalEffect$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.FinalActionAction),
switchMap(action => {
this.store.pipe(select(fromData.data1)).subscribe(data1 => {this.data1 = data1});
this.store.pipe(select(fromData.data2)).subscribe(data1 => {this.data2 = data2});
// this.data1, this.data2 are empty...
return [new finalAction()];
})
);
В someEffect$
оба getData1
и getData2
вызывают http-запрос и сохраняют, когда http-вызов успешно выполнен.
Проблема в том, что он не ждет, пока данные будут сохранены в хранилище. И просто finalAction
выполняется.
Я понимаю почему, потому что flatMap
подождите, пока getData1
это не будет сделано. Но нет GetData1Success
.
В этом случае, как я могу правильно получить данные из хранилища в момент finalEffect$
?
Спасибо.
РЕДАКТИРОВАТЬ 1: я уже пробовал использовать forkJoin
. Но я понятия не имею, как перехватывать данные, когда они хранятся в хранилище.
Комментарии:
1. Это потому, что вы передаете http-запрос для вашей карты. Это должно быть перемещено в исходный канал
2. @Clouse24 Можете ли вы рассказать мне более подробно? Где находится «исходный канал»?
3. взгляните на оператор forkJoin
4. @timdeschryver Я действительно пробовал forkJoin (я часто использовал его до использования Ngrx). Однако я понятия не имею, как решить мою проблему с forkJoin. В моем случае я должен вызвать два действия. но как я могу использовать forkJoin и отслеживать, выполнены ли эти действия и сохранены ли данные в хранилище? Спасибо.
Ответ №1:
Я мог бы решить с помощью forkJoin
. Но не уверен, что это чистый способ.
Дайте мне знать ваше мнение.
Итак, моим решением было изменение второго кода из приведенного выше.
@Effect()
someEffect$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.UserLogIn),
switchMap(_ => {
const data1 = this.httpClient.get(...);
const data2 = this.httpClient.get(...);
return forkJoin(data1, data2).pipe(
tap(
result => {
// Here update data to the store.
this.store.dispatch(GetData1Success(result[0]));
this.store.dispatch(GetData2Success(result[1]));
}
)
)
}),
switchMap(action => { // run final action
return [new finalAction()];
}),
catchError(() => of(new finalActionFailure()))
);
У меня уже есть вызванное действие, GetData1
которое получает data1, но я не смог использовать это действие в моем случае, потому что я понятия не имею, как уловить момент, когда data1 сохраняется в store
.
И в конечном итоге использовал forkJoin
с вызовом http-запроса вручную в switchMap
.