Reputation: 7609
I am using redux, redux-observable in react.
I have the following
const goToItemEpic = (action$, state$): Observable<any> => action$.pipe(
ofType(ItemsDetailsActions.goToItem),
concatMap((action: {payload: {projectId: string; datastoreId: string; itemId: string}}) =>
of(ProjectActions.setCurrentProjectId({projectId: action.payload.projectId})).pipe(
delay(1000),
switchMap(() => {
return [
DatastoreActions.setCurrentDatastoreId({datastoreId: action.payload.datastoreId}),
ItemsActions.setCurrentItemId({ itemId: action.payload.itemId })
];
})
)
)
);
Basically, I would like to dispatch setCurrentProjectId
then wait for some time, and then dispatch
setCurrentDatastoreId
and setCurrentItemId
I face two problems :
1) The current code delay setCurrentDatastoreId
and setCurrentItemId
but do not execute setCurrentProjectId
, why ?
2) Here the delay is an hardcoded 1000ms. but I would like to delay based on another observable execution getDatastoresSuccess
so the it would be
execute => setCurrentProjectId
waitFor => getDatastoresSuccess
execute => setCurrentDatastoreId
execute => setCurrentItemId
How do I manage to do that in redux-observable?
EDIT :
const goToItemEpic = (action$, state$): Observable<any> => action$.pipe(
ofType(ItemsDetailsActions.goToItem),
concatMap((action: {payload: {projectId: string; datastoreId: string; itemId: string}}) =>
concat(
ProjectActions.setCurrentProjectId({projectId: action.payload.projectId}),
action$.pipe(
ofType(DatastoreActions.getDatastoresSuccess),
first(),
switchMap(() => of(
DatastoreActions.setCurrentDatastoreId({datastoreId: action.payload.datastoreId}),
ItemsActions.setCurrentItemId({ itemId: action.payload.itemId })
))
)
)
)
);
subscribeTo.js:23 Uncaught TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
Upvotes: 1
Views: 428
Reputation: 7564
You can do that by using action$.pipe
again to wait for the required action:
const goToItemEpic = (action$, state$): Observable<any> => action$.pipe(
ofType(ItemsDetailsActions.goToItem),
concatMap((action: {payload: {projectId: string; datastoreId: string; itemId: string}}) =>
concat(
of(ProjectActions.setCurrentProjectId({projectId: action.payload.projectId})),
action$.pipe(
ofType(ItemsDetailsActions.getDatastoresSuccess),
first(),
switchMap(() => of(
DatastoreActions.setCurrentDatastoreId({datastoreId: action.payload.datastoreId}),
ItemsActions.setCurrentItemId({ itemId: action.payload.itemId })
)
})
So in the concat
you first emit the ProjectActions.setCurrentProjectId
action and after that wait for the first()
action of type getDatastoresSuccess
and map this to setCurrentDatastoreId
and setCurrentItemId
The answer to your question 1) is that setCurrentProjectId
is used as the (ignored) input of switchMap
, which is then mapped to setCurrentDatastoreId
and setCurrentItemId
Upvotes: 2