Try   HackMD

Redux API middleware B-S-F

  • B-S-F

    • Begin
    • Success
    • Faild

Indroduction

  • This is easy way to dispatch

    • apiCallBegan (ACTION_NAME_REQUEST)
    • apiCallSuccess (ACTION_NAME_SUCCESS)
    • apiCallFailed (ACTION_NAME_FAILED)

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • We even don't need to separate those three action status for each action request.

    something like:

    ​​​​​​  export const ORDER_DETAILS_REQUEST = 'ORDER_DETAILS_REQUEST';
    ​​​​​​  export const ORDER_DETAILS_SUCCESS = 'ORDER_DETAILS_SUCCESS';
    ​​​​​​  export const ORDER_DETAILS_FAIL = 'ORDER_DETAILS_FAIL';
    

example

In below, we using @reduxjs/toolkit as redux framework

store/api.js

​​​​import { createAction } from "@reduxjs/toolkit";

​​​​export const apiCallBegan = createAction("api/CallBegan");
​​​​export const apiCallSuccess = createAction("api/CallSuccess");
​​​​export const apiCallFaild = createAction("api/CallFaild");

store/middleware/api.js

​​​​import axios from 'axios';
​​​​import * as actions from '../api';

​​​​const api = ({ dispatch }) => (next) => async (action) => {
​​​​  if (action.type !== actions.apiCallBegan.type) return next(action);

​​​​  const { url, method, onStart, data, onSuccess, onError } = action.payload;

​​​​  if (onStart) dispatch({ type: onStart });

​​​​  next(action);

​​​​  try {
​​​​    const response = await axios.request({
​​​​      baseURL: 'http://localhost:9001/api',
​​​​      url,
​​​​      method,
​​​​      data,
​​​​    });

​​​​    // General
​​​​    dispatch(actions.apiCallSuccess(response.data));
​​​​    // Specific
​​​​    if (onSuccess) dispatch({ type: onSuccess, payload: response.data });
​​​​  } catch (error) {
​​​​    // General
​​​​    dispatch(actions.apiCallFaild(error.message));
​​​​    // Specific
​​​​    if (onError) dispatch({ type: onError, payload: error.message });
​​​​  }
​​​​};

​​​​export default api;

store/configureStore.js

​​​​import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
​​​​import reducer from './reducer';
​​​​import api from './middleware/api';

​​​​export default function () {
​​​​  return configureStore({
​​​​    reducer,
​​​​    middleware: [
​​​​      ...getDefaultMiddleware(),
​​​​      api,
​​​​    ],
​​​​  });
​​​​}

implement

store/bug.js

​​​​const slice = createSlice({
​​​​  name: 'bugs',
​​​​  initialState: {
​​​​    list: [],
​​​​    loading: false,
​​​​    lastFetch: null,
​​​​  },
​​​​  reducers: {
​​​​    bugAdded: (bugs, action) => {
​​​​      bugs.list.push(action.payload);
​​​​    }
​​​​  },
​​​​});

​​​​export const addBug = (bug) =>
​​​​  apiCallBegan({
​​​​    url,
​​​​    method: 'post',
​​​​    data: bug,
​​​​    onSuccess: bugAdded.type,
​​​​  });

Note

When using jest to testing your app,
should remember,
api middleware must be above all others middleware except getDefaultMiddleware().
if you don't,
infinite error will comming !