Skip to content

Instantly share code, notes, and snippets.

@andreystarkov
Created May 22, 2019 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreystarkov/06c0c64157d1b0867ca6a1ffe2aff82c to your computer and use it in GitHub Desktop.
Save andreystarkov/06c0c64157d1b0867ca6a1ffe2aff82c to your computer and use it in GitHub Desktop.
Universal Saga: Magic helper for handling api-calls with its side effects
import { call, put, takeEvery, select } from 'redux-saga/effects'
// все экшены названы по паттерну _REQUEST, _SUCCESS, _FAILED
// like AUTH_SUCCESS, AUTH_FAILED, AUTH_REQUEST
function * callAPI (action) {
const { payload, data: { method, params } } = action
const user = yield select(state => state.user)
try {
const authHeaders = user.headers
const response = yield call(method, { ...params, authHeaders })
if (!response.ok) {
throw response
}
// если все ок переделывает экшен на _SUCCESS
const newType = action.type.replace('_REQUEST', '_SUCCESS')
// вызываем экшн _SUCCESS и передаем данные в стейт
yield put({ type: newType, payload, response, params })
} catch (e) {
// если все плохо переделываем экшен на _FAILED
const newType = action.type.replace('_REQUEST', '_FAILED')
// заносим в стейт статус беды
yield put({
type: newType,
problem: e.problem,
status: e.status,
payload,
response: e
})
}
}
// эта штука палит все реквест-экшены и перенаправляет их в сагу callApi
export default function * watchRequest () {
yield takeEvery(action => /^.*_REQUEST/.test(action.type), callAPI)
}
// эксперментальные версия для GraphQL
function * graphApi (action) {
const { payload, data: { method, params } } = action
const user = yield select(state => state.user)
const currentWallet = yield select(state => state.currentWallet)
const bankId = currentWallet.id
try {
const authHeaders = user.headers
const response = yield call(method, { bankId, ...params, authHeaders })
if (
(response.data && response.data.errors) ||
response.errors
) {
throw response
}
const newType = action.type.replace('_GRAPHQL', '_SUCCESS')
yield put({ type: newType, payload, response, params })
} catch (e) {
const newType = action.type.replace('_GRAPHQL', '_FAILED')
yield put({
type: newType,
problem: e.problem,
status: e.status,
payload,
response: e
})
}
}
export function * watchGraphql () {
yield takeEvery(action => /^.*_GRAPHQL/.test(action.type), graphApi)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment