Usage docs Reference Examples

src/tracking/accounts/accountsSaga.js

import {
  call, fork, put, select, takeEvery, takeLatest
} from 'redux-saga/effects';
import * as accountsAT from './AT';
import poller from '../../util/poller';

function* tryFetchAccounts(web3) {
  try {
    // fetch the accounts from web3
    const accounts = yield call(web3.eth.getAccounts);

    // TODO: do we like this as behavior? Or is no accounts a valid fetch result?
    if (!accounts) {
      throw new Error('No accounts available.');
    }

    // Simply create make the reducer handle the new accounts;
    //  old accounts will be filtered, new accounts added.
    yield put({type: accountsAT.ACCOUNTS_FETCH_COMPLETED, accounts});
  } catch (err) {
    yield put({type: accountsAT.ACCOUNTS_FETCH_FAILED, err});
  }
}
// TODO should accounts be fetched automatically on interval?

function* tryGetBalance(web3, {account}) {
  try {
    const balance = yield call(web3.eth.getBalance, account);

    yield put({type: accountsAT.ACCOUNT_BALANCE, account, balance});
  } catch (err) {
    yield put({type: accountsAT.ACCOUNT_GET_BALANCE_FAILED, account, err});
  }
}

function* getSingle({account}) {
  // No other data than just the balance for now.
  yield put({type: accountsAT.ACCOUNT_GET_BALANCE, account});
}

function* getAll(getAccountsState) {
  const accounts = yield select(getAccountsState);

  // Get wallet accounts
  for (const account of Object.keys(accounts.wallet)) {
    yield put({type: accountsAT.ACCOUNT_GET, account});
  }

  // Get local accounts (tracked, but not part of wallet)
  for (const account of Object.keys(accounts.local)) {
    yield put({type: accountsAT.ACCOUNT_GET, account});
  }
}

function* accountsPollWorker(web3, getAccountsState) {
  yield call(tryFetchAccounts, web3);
  yield call(getAll, getAccountsState);
}

function* accountsPollError(err) {
  yield put({type: accountsAT.ACCOUNTS_POLL_ERROR, err: err.message});
}

function* accountsSaga(web3, getAccountsState) {
  yield fork(poller(
    accountsAT.ACCOUNTS_START_POLLING,
    accountsAT.ACCOUNTS_STOP_POLLING,
    accountsPollWorker,
    accountsPollError,
    web3, getAccountsState
  ));
  // only take latest, doing multiple buffered updates is useless.
  yield takeLatest(accountsAT.ACCOUNTS_START_FETCH, tryFetchAccounts, web3);
  yield takeLatest(accountsAT.ACCOUNTS_GET_ALL, getAll, getAccountsState);
  yield takeEvery(accountsAT.ACCOUNT_GET, getSingle);
  yield takeEvery(accountsAT.ACCOUNT_GET_BALANCE, tryGetBalance, web3);
}

export default accountsSaga;