Eyal
Eyal

Reputation: 1709

Can't get takeUntil to cancel the request

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:

  1. SEARCH
  2. SEARCH
  3. SEARCH
  4. SEARCH
  5. CLEAR_SEARCH_RESULTS
  6. SEARCH_SUCCESS

(each SEARCH is a keystroke)

Upvotes: 1

Views: 496

Answers (1)

Eyal
Eyal

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

Related Questions