simpleAsync

Peter Gundel edited this page Jul 7, 2017 · 3 revisions

Source

Warning: The simpleAsync feature is currently under consideration and we expect heavy (breaking) API changes.

Side-effects with redux-saga

Using the redux-belt generated actions, you can write sagas that make use of the meta object:

import { types } from './actions'
import { requestAddBook } from './api'

function* asyncAddBook(action) {
  try {
    const response = yield call(requestAddBook, action.payload)
    yield put({ type: action.meta.success, payload: response.data })
  } catch (error) {
    yield put({ type: action.meta.failure, payload: error })
  }
}

function* booksSaga() {
  yield takeEvery(types.ADD_BOOK, asyncAddBook)
}

A frequent use case for a saga is to wrap Redux actions around a network request, or an impure function, or whatever it is that takes time to complete. In the simplest (and most common) scenario, a saga tries to perform a task. If it succeeds, it dispatches a success action. If it fails, it dispatches a failure action. For all these use cases, redux-belt provides the simpleAsync function, which works with redux-belt generated actions:

import { simpleAsync } from 'redux-belt'

// This does exactly the same as the example saga above
const asyncAddBook = simpleAsync({ effect: requestAddBook })

function* booksSaga() {
  yield takeEvery(types.ADD_BOOK, asyncAddBook)
}

/**
 * Now, calling addBook with an argument like this:
 * addBook({ id: 1, title: 'The Stranger', author: 'Albert Camus' })
 *
 * Will trigger asyncAddBook, which will call requestAddBook with exactly the same payload:
 * { id: 1, title: 'The Stranger', author: 'Albert Camus' }
 */

In a more complicated scenario, a saga could call yet another set of actions on success. You can do this with simpleAsync by providing a function to the afterSuccess key. The function provided to afterSuccess will be called with two arguments: the original payload passed to the action and the response from the effect. You can choose to pass whichever you want, in this case we're passing the response:

import { simpleAsync } from 'redux-belt'

const asyncAddBook = simpleAsync({
  effect: requestAddBook,
  afterSuccess: (payload, response) => addBookSuggestions(response)
})

function* booksSaga() {
  yield takeEvery(types.ADD_BOOK, asyncAddBook)
}

In a reducer, you can react to the actions dispatched by these sagas like so:

import { types } from './actions'

function booksReducer(state = {}, action) {
  switch (action.type) {
    case types.ADD_BOOK:
      // Do something
    case types.ADD_BOOK_SUCCESS:
      // Do something
    case types.ADD_BOOK_FAILURE:
      // Do something
    default:
      return state
  }
}
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.