title: Using call and put in redux-saga, the right way
body: <p>I'm using redux-saga in my React application. However, I'm a bit confused of how call and put effects should be implemented in the right way.</p>
  <p>I want to add new data to my redux state, but whenever I use the set up listed bellow, new transactions object appears in my UI, but not in the JSON Server. If I refresh the page, the newly added item disappears.</p>
  <p>One of the reasons my set up looks exactly like this is that I read that actions should be implemented with put effect whenever dispatching an action and that it's good for testing your Redux Saga.</p>
  <p>What is the right way to use put effect in my situation?</p>
  <p>I have the following set up:</p>
  <p><strong>Redux Saga</strong></p>
  <pre><code>import { put, call, take, takeLatest} from &quot;redux-saga/effects&quot;;
  
  import {
    ADD_TRANSACTION,
    addTransaction
  } from &quot;state/transactions&quot;;
  // POST
  async function addTransactionData(payload) {
    try {
      const response = await fetch(`http://localhost:3010/transactions`, {
        method: &quot;POST&quot;,
        headers: {
          &quot;Content-Type&quot;: &quot;application/json&quot;
        },
        body: JSON.stringify(payload)
      });
      const result = await response.json(payload);
      return result;
    } catch (error) {
      throw error;
    }
  }
  
  function* onAddTransactionData({ payload }) {
    try {
      const data = yield call(addTransactionData, payload);
      yield put(addTransaction(data));
    } catch (error) {
      console.log(error);
    }
  }
  
  export function* addTransactionWatcherSaga() {
    yield take(ADD_TRANSACTION, onAddTransactionData);
  }
  </code></pre>
  <p><strong>Root Saga</strong></p>
  <pre><code>import { all, call } from &quot;redux-saga/effects&quot;;
  import {
    transactionsWatcherSaga,
    removeTransactionWatcherSaga,
    addTransactionWatcherSaga
  } from &quot;state/transactions&quot;;
  
  export function* rootSaga() {
    yield all([
      call(transactionsWatcherSaga),
      call(removeTransactionWatcherSaga),
      call(addTransactionWatcherSaga)
    ]);
  }
  </code></pre>
  <p><strong>Action creators</strong></p>
  <pre><code>// ....
  export const addTransaction = ({
    name,
    amount,
    description,
    isExpense
  } = {}) =&gt; {
    return {
      type: ADD_TRANSACTION,
      payload: {
        id: uuidv4(),
        name,
        amount,
        description,
        isExpense
      }
    };
  };
  //...
  </code></pre>
  <p><strong>Reducer</strong></p>
  <pre><code>/* ==============================================
  ============== TRANSACTIONS REDUCER ============
  =============================================== */
  import {
    ADD_TRANSACTION,
    REMOVE_TRANSACTION,
    EDIT_TRANSACTION,
    GET_TRANSACTIONS,
    SET_TRANSACTIONS
  } from &quot;state/transactions&quot;;
  
  const initialState = {
    transactions: [],
    transactionsLoader: false,
    error: {
      message: &quot;&quot;
    }
  };
  
  export const transactionsReducer = (state = initialState, action) =&gt; {
    switch (action.type) {
     // ...
      case ADD_TRANSACTION:
        return {
          ...state,
          transactions: [...state.transactions, action.payload]
        };
     // ....
      default:
        return state;
    }
  };
  
  </code></pre>
  <p>The only way I can succesfully dispatch a POST request is this, but that does not include put effect.</p>
  <pre><code>// POST
  async function addTransactionData(payload) {
    try {
      const response = await fetch(`http://localhost:3010/transactions`, {
        method: &quot;POST&quot;,
        headers: {
          &quot;Content-Type&quot;: &quot;application/json&quot;
        },
        body: JSON.stringify(payload)
      });
      const result = await response.json(payload);
      console.log(result);
      return result;
    } catch (error) {
      throw error;
    }
  }
  
  function* onAddTransactionData({ payload }) {
    console.log(payload);
  
    try {
      yield call(addTransactionData, payload);
    } catch (error) {
      console.log(error);
    }
  }
  
  export function* addTransactionWatcherSaga() {
    yield takeLatest(ADD_TRANSACTION, onAddTransactionData);
  }
  
  </code></pre>