Reputation: 1709
After dispatching SEARCH
, I'm trying to cancel an AJAX request but also to keep the observable listening. I'm using takeUntil
and waiting for an action of type CLEAR_SEARCH_RESULTS
to cancel the request.
Here's my epic:
const searchEpic = action$ =>
action$.ofType(SEARCH).pipe(
debounceTime(500),
switchMap(({ payload }) =>
search(query).pipe(
map(({ response }) => SearchActions.searchSuccess(response)), // dispatches SEARCH_SUCCESS
takeUntil(
action$.ofType(CLEAR_SEARCH_RESULTS)
)
)
)
)
Edit: I have a Redux logger which outputs dispatched actions in the following order:
SEARCH
SEARCH
SEARCH
SEARCH
CLEAR_SEARCH_RESULTS
SEARCH_SUCCESS
(each SEARCH
is a keystroke)
Upvotes: 1
Views: 496
Reputation: 1709
I solved it by moving the takeUntil
outside of the switchMap
and putting a repeat()
after it, like so:
const searchEpic = action$ =>
action$.ofType(SEARCH).pipe(
debounceTime(500),
switchMap(({ payload }) =>
search(query).pipe(
map(({ response }) => SearchActions.searchSuccess(response))
)
),
takeUntil(action$.ofType(CLEAR_SEARCH_RESULTS)),
repeat()
)
The problem was that the epic starts listening for CLEAR_SEARCH_RESULTS
only after the 500ms of the debounceTime
, which is not what I wanted.
All credit goes to this answer by Jay Phelps and to Evert Bouw for finding and pointing it out to me on Gitter.
Upvotes: 1