Skip to content

Instantly share code, notes, and snippets.

@chasevida
Last active January 21, 2020 01:20
Show Gist options
  • Save chasevida/bb250d9fd7ea0c21ab8201fe54299205 to your computer and use it in GitHub Desktop.
Save chasevida/bb250d9fd7ea0c21ab8201fe54299205 to your computer and use it in GitHub Desktop.
Redux Observable / RXJS request effect helper (when you need to get some external auth for headers etc.)
import { of } from 'rxjs'
import { ajax } from 'rxjs/ajax'
import { mergeMap, catchError, flatMap } from 'rxjs/operators'
import { ofType } from 'redux-observable'
import { getAuthClient } from 'auth' // replace with your own auth client
const createAuthHeaderRequest = ({ debug }) => async () => {
const authClient = getAuthClient()
const accessToken = await authClient.getTokenSilently()
if (debug) {
const authClientAvailable = authClient
? 'available'
: 'unavailable'
console.log('[debug - auth client]', authClientAvailable) // eslint-disable-line
console.log('[debug - auth token]', accessToken) // eslint-disable-line
}
return {
headers: {
Authorization: `Bearer ${accessToken}`,
}
}
}
const defaultSuccessHandler = (payload = {}) => ({
type: 'request_success',
payload,
})
const defaultErrorHandler = (payload = {}) => ({
type: 'request_error',
payload,
})
export const makeRequestEffect = ({
url,
headers: defaultHeaders = {},
onSuccess = defaultSuccessHandler,
onError = defaultErrorHandler,
debug,
debugAuth,
}) => ([
flatMap(createAuthHeaderRequest({ debug: debugAuth })),
mergeMap(
({ headers }) =>
ajax
.get(url, { ...defaultHeaders, ...headers })
.pipe(
mergeMap(({ response }) => {
if (debug) {
console.log('[debug (api response)]', JSON.stringify(response, null, 2)) // eslint-disable-line
}
if (typeof onSuccess === 'string') {
return of({
type: onSuccess,
payload: response,
})
}
return of(onSuccess(response))
}),
catchError(error => {
const err = (error && error.message) || error
if (debug) {
console.error('[debug (api error)]', err) // eslint-disable-line
}
return of(onError(err))
})
),
),
])
export const makeActionRequestEffect = ({ type, ...rest }) =>
(action$, state$) =>
action$.pipe(
ofType(type),
...makeRequestEffect(rest),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment