Muhammad Awais Kayani
Muhammad Awais Kayani

Reputation: 366

Redux toolkit: How to handle multiple api calls with extra builder?

I just start using Redux-toolkit and have very less knowledge about it ,so the question is: the API calls are written in extra builder but what if we have to use multiple API call in same slice how to achieve it?

Upvotes: 2

Views: 5907

Answers (2)

Mahendra Meghwal
Mahendra Meghwal

Reputation: 27

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

const initialState = {
  data1: null,
  data2: null,
  loading: false,
  error: null,
};

// Define your API calls using createAsyncThunk
export const fetchData1 = createAsyncThunk('sliceName/fetchData1', async () => {
  const response = await fetch('your/api/endpoint1');
  return response.json();
});

export const fetchData2 = createAsyncThunk('sliceName/fetchData2', async () => {
  const response = await fetch('your/api/endpoint2');
  return response.json();
});

const mySlice = createSlice({
  name: 'sliceName',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchData1.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchData1.fulfilled, (state, action) => {
        state.loading = false;
        state.data1 = action.payload;
      })
      .addCase(fetchData1.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      })
      .addCase(fetchData2.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchData2.fulfilled, (state, action) => {
        state.loading = false;
        state.data2 = action.payload;
      })
      .addCase(fetchData2.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  },
});

export default mySlice.reducer;

Upvotes: 1

Julien Kode
Julien Kode

Reputation: 5479

You can plug your api call with extraReducers

import { createSlice, isAnyOf } from '@reduxjs/toolkit'
import { apiOne } from '../../app/services/apiOne'
import { apiTwo } from '../../app/services/apiTwo'
import type { RootState } from '../../app/store'

type StuffState = {
  isGood: boolean
}

const slice = createSlice({
  name: 'stuff',
  initialState: { isGood: false },
  reducers: {},
  extraReducers: (builder) => {
    builder.addMatcher(
      apiTwo.endpoints.login.matchFulfilled,
      (state, { payload }) => {
        state.isGood = true
      }
    )

    builder.addMatcher(
      apiOne.endpoints.login.matchFulfilled,
      (state, { payload }) => {
        state.isGood = payload.isGood
      }
    )
  },
})

export default slice.reducer

You can also create a matcher with your two queries

import { createSlice } from '@reduxjs/toolkit'
import { apiOne } from '../../app/services/apiOne'
import { apiTwo } from '../../app/services/apiTwo'
import type { RootState } from '../../app/store'

type StuffState = {
  isGood: boolean
}

const slice = createSlice({
  name: 'stuff',
  initialState: { isGood: false },
  reducers: {},
  extraReducers: (builder) => {
    builder.addMatcher(
      isAnyOf(apiOne.endpoints.login.matchFulfilled, apiTwo.endpoints.login.matchFulfilled),
      (state, { payload }) => {
        state.isGood = true
      }
    )
  },
})

export default slice.reducer

Upvotes: 4

Related Questions