I've just started learning redux-observables and RxJS for work recently. We have alerts globally set in Redux. I want to be able to set an alert, then after a set period, close that same alert. There can also be multiple alerts at any time, and the user could manually close one alert before it automatically closes itself. I have added to id here, so I can close the correct alert. I have attempted to use delay after the initial map than another map to achieve this so far. However, this skips the first map.
export const addAlertEpic: Epic<Action, Action, RootState> = (
action$,
state$
) =>
action$.pipe(
ofType(slice.actions.addAlert),
map((values: any) =>
slice.actions.addAlertSuccess({ id: uuid(), ...values.payload })
)
);
Thank you for help!
set an alert, then after a set period, close that same alert [...] he user could manually close one alert before it automatically closes itself
With that in mind, here would be my approach:
actions$.pipe(
ofType(slice.actions.addAlert),
// `There can also be multiple alerts at any time`
mergeMap(action => {
const id = uuid();
// using `NEVER` is important, it's essentially the same as new Observable(() => {})
// it is needed because we don't want the inner observable to complete unless `takeUntil` decides to
return NEVER
.pipe(
// start with opening the alert
startWith(slice.actions.addAlertSuccess({ id, ...action.payload }))
// close the alert either
takeUntil(merge(
// when `TIME` expires
timer(TIME),
// or when the user decides to
userClosedActions.pipe(
filter(action => action.id === id)
)
)),
// at the end(when the stream completed due to `takeUntil`), close the alert
endWith(slice.actions.closeAlertSuccess(...))
)
})
)
userClosedActions
can be a Subject
that sends next
notifications as a result of user action. For example:
onClick (closedId) {
userClosedActions.next({ id: closedId })
}