1

I am using redux toolkit with thunk to receive data from api.
I need to fetch data from 2 apis in consecutive order using data I got from the first api call as a argument of second api call (search1 first, then search2)
In order to do that, I need to wait for the first dispatch to fully complete its job from calling getSearch1 to updating the state.

Please help!

// store
import { configureStore } from "@reduxjs/toolkit";
import searchReducer from "./slice/searchSlice";

export const store = configureStore({
  reducer: {
    search: searchReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
// slice
export const getSearch1 = createAsyncThunk(
  "search/getSearch1",
  async (args: string[]) => {
    const result = await ApiUtil.search1(args);
    return result;
  }
);

export const getSearch2 = createAsyncThunk(
  "search/getSearch2",
  async (ids: string[]) => {
    const result = await ApiUtil.search2(ids);
    return result;
  }
);

export const searchSlice = createSlice({
  name: "search",
  initialState,
  reducers: {...},
  extraReducers: (builder) => {
    builder
      .addCase(getSearch1.fulfilled, (state, action) => {
        state.search1 = action.payload;
      })
      .addCase(getSearch2.fulfilled, (state, action) => {
        state.search2 = action.payload;
      });
  },
});
// home page
import {
  ...
  getSearch1,
  getSearch2,
} from "../../redux/slice/searchSlice";

  const handleSearch = () => {
    dispatch(getSearch1(args));
    const ids = search1?.map((item) => item.id.toString());
    dispatch(getSearch2(ids ?? []));
    history.push(ROUTES.RESULT_PAGE, search1);
  };
GCnomore
  • 104
  • 2
  • 6
  • Does this answer your question? https://stackoverflow.com/questions/67016311/how-to-deal-with-the-dependency-between-two-async-thunks – Lin Du Nov 30 '21 at 03:34
  • Thank you so much! I should've dig into redux toolkit docs a bit more – GCnomore Nov 30 '21 at 18:40

3 Answers3

1

You can use .unwrap() method to achieve that,see the documentation :

  try {
    const { data } = await dispatch(getSearch1(args)).unwrap()
    await dispatch(getSearch2(data ?? []));
    // handle result here
  } catch (rejectedValueOrSerializedError) {
    // handle error here
  }
Jood80
  • 124
  • 2
  • 4
0

I solved it just as slideshowp2's shared link.

  useEffect(() => {
    getResult();
  }, [dispatch]);   // listen for dispatch(), should run getResult() twice

  const getResult = async () => {
    let action;
    if (!search1) {   // skip below when called twice
      action = await dispatch(getSearch1(args));
    }
    if (isFulfilled(action)) {
      const id = action.payload.map((item) => item.id.toString());
      dispatch(getSearch2(id ?? []));
    }
  };
GCnomore
  • 104
  • 2
  • 6
0
 dispatch(
          deleteEventDeteailsThunk({
            id: deletedIdEvents[0].id
          })
        )
          .unwrap()
          .then((resp) => {
            // handle result here
            res(deletedId);
          })`enter code here`
          .catch((err) => {
            // handle error here
            res({});
          });

for refrence:https://redux-toolkit.js.org/api/createAsyncThunk#unwrapping-result-actions