Skip to content

Instantly share code, notes, and snippets.

@nurmdrafi
Last active April 4, 2023 14:28
Show Gist options
  • Save nurmdrafi/76f1d0337a5d5c0966c03d0b4eeb29ff to your computer and use it in GitHub Desktop.
Save nurmdrafi/76f1d0337a5d5c0966c03d0b4eeb29ff to your computer and use it in GitHub Desktop.
Redux State CRUD with createAsyncThunk

Action

import { createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

// Import API's
import { API } from "../../App.config";

// Token & Headers
const token = localStorage.getItem('token')
const headers = { headers: { Authorization: `Bearer ${ token }`} }

// GET ZONES
export const getZones = createAsyncThunk("zone/getZones", async () => {
  try {
    const res = await axios.get(API.ZONE, headers);
    return res.data;
  } catch (error) {
    console.error(error);
  }
});

// DELETE ZONE
export const deleteZone = createAsyncThunk("zone/deleteZone", async (id) => {
  try {
    const res = await axios.delete(`${API.ZONE}/${id}`, headers);
    return res.data;
  } catch (error) {
    return error.message;
  }
});

// UPDATE ZONE
export const updateZone = createAsyncThunk(
  "zone/updateZone",
  async (updatedZone) => {
    try {
      const res = await axios.put(
        `${API.ZONE}/${updatedZone.id}`,
        updatedZone,
        headers
      );
      return res.data;
    } catch (error) {
      return error.message;
    }
  }
);

// ADD Zone
export const addZone = createAsyncThunk("zone/addZone", async (newZone) => {
  try {
    const res = await axios.post(`${API.ZONE}`, newZone, headers);
    return res.data;
  } catch (error) {
    return error.message;
  }
});

Reducer

import { createSlice } from "@reduxjs/toolkit";

import {
  getZones,
  deleteZone,
  updateZone,
  addZone,
} from "../actions/zoneActions";

const initialState = {
  zones: null,
  loading: false,
  error: null,
  isSuccess: false,
};

const zoneSlice = createSlice({
  name: "zone",
  initialState,
  extraReducers: (builder) => {
    // GET ZONES
    builder.addCase(getZones.pending, (state, action) => {
      state.loading = true;
    });
    builder.addCase(getZones.fulfilled, (state, action) => {
      state.loading = false;
      state.zones = action.payload?.zones;
      state.isSuccess = true;
    });
    builder.addCase(getZones.rejected, (state, action) => {
      state.loading = false;
      state.isSuccess = false;
      state.error = action.payload?.message;
    });
    // DELETE ZONE
    builder.addCase(deleteZone.fulfilled, (state, action) => {
      state.zones = state.zones.filter((zone) => zone.id !== action.payload);
      state.isSuccess = true;
    });
    builder.addCase(deleteZone.rejected, (state, action) => {
      state.isSuccess = false;
      state.error = action.payload?.message;
    });
    // UPDATE ZONE
    builder.addCase(updateZone.fulfilled, (state, action) => {
      const index = state.zones.findIndex(
        (zone) => zone.id === action.payload?.id
      );
      state[index] = {
        ...state[index],
        ...action.payload,
      };
      state.isSuccess = true;
    });
    builder.addCase(updateZone.rejected, (state, action) => {
      state.isSuccess = false;
      state.error = action.payload?.message;
    });
    // ADD ZONE
    builder.addCase(addZone.fulfilled, (state, action) => {
      state.zones.push(action.payload?.zone);
      state.isSuccess = true;
    });
    builder.addCase(addZone.rejected, (state, action) => {
      state.isSuccess = false;
      state.error = action.payload?.message;
    });
  },
});

export default zoneSlice.reducer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment