score:2

Accepted answer
const doDispatch = async () => {
  const action = await dispatch(postSpotifyAlbums(obj));
  console.log("result", action);
  // we could have the success or the failure action
  if ( action.type === postSpotifyAlbums.fulfilled.type) {
    // do something with success
    const data = action.payload;
  } else {
    // do something with error
    const error = action.error;
  }
};

score:1

// store.js

import {middleware as thunkMiddleware} from 'redux-saga-thunk';
const middlewares = [thunkMiddleware];
const sagaMiddleware = createSagaMiddleware();
middlewares.push(sagaMiddleware);
if (process.env.NODE_ENV === `development`) {
  const {logger} = require(`redux-logger`);

  middlewares.push(logger);
}

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  white: ['errors'],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: middlewares,
  devTools: process.env.NODE_ENV === `development` ? true : false,
});

// Payment.js(or any of your component)

const handleBtnClick = async (type, value) => {
    console.log('btn click type', type, route.params, value);
    switch (type) {
      case 'pay':
        try {
          let orderId = 'OD_' + moment().format('YYYYMMDDHHmmss');
          // Here we are dispatching action "INITIATE_TRANSACTION" to redux saga.
          // Step 1.
          const response = await props.initiatePayment({
            orderId,
            orderAmount: 10,
            orderCurrency: 'INR',
          });

          console.log('response', response.data.cftoken);
          }catch (error){
          console.log('error', error)
          }
          break;
}

// Middleware used is redux-saga-thunk, which basically implements functionality of thunk in redux saga. so meta: {thunk: true} waits for the whole execution to finish and then continues.
// Step 2
export const initiatePayment = data => ({
  type: INITIATE_TRANSACTION,
  data,
  meta: {thunk: true},
});

//Step 3
// Here post is just a custom function for api call, onError and onSuccess are the handler functions and safe is the wrapper method which basically implements try catch logic and handles errors for us without repeating much of the code.

// paymentSaga.js
function* initiateTransactionSaga({data, meta}) {
  const response = yield call(post, API.INITIATE_TRANSACTION, data);
  return response; //Step 4....
}

export default function* paymentSaga() {
  yield takeLatest(
    INITIATE_TRANSACTION,
    safe(onError, initiateTransactionSaga, onSuccess), //onSuccess required if you want values to be returned to step 1
  );
}

// axiosApi.js

export async function post(url, data, config = {}) {
  console.log('url data config', url, data, config);
  return axiosApi
    .post(url, {...data}, {...config})
    .then(response => response.data);
}

// Sagahelper.js


/**
 * @param handler --- Error handler function. In our case, onError Function
 * @param saga --- Actual Saga function. in our case Api is called and data is returned
 * @param success --- success redux action dispatch function -- in our case, if we need to pass response coming from api to the actual calling function( something like props.viewingItem(data)), then pass it here, otherwise leave it blank
 * @
 */

export const safe = (
  handler: any = null,
  saga: any,
  success: any = null,
  ...args: any
) =>
  function* (action: any) {
    try {
      console.log('action in safe===', action, success);
      const res1 = yield call(saga, ...args, action);
      // Success wrapper. if you pass onSuccess method, then only this part will be executed. If you do not want the values to be returned from redux-saga to your component function call, then i suggest you skip it.
      if (success) {
        yield call(success, res1, action.type, action.meta);
        return res1; //This line returns value to the component function( to step 1)
      }
    } catch (err) {
      yield call(handler, ...args, err, action.type, action.meta);
    }
  };

export function* onError(err: any, type: any, meta: any) {
  console.log('type onError', type);
  yield put({
    type: type + '_ERROR',
    payload: err,
    error: true,
    meta,
  });
  
  // Do something with the error msg. like show alert, etc...
  return err;
}

export function* onSuccess(response: any, type: any, meta: any) {
  console.log('type onError', response);
  yield put({
    type: type + '_SUCCESS',
    payload: response,
    error: false,
    meta,
  });
  // Do something with the success msg. like show alert, etc...
  return response;
}

Related Query

More Query from same tag