Search code examples
reduxfetchredux-thunkredux-toolkit

Action Thunk not triggering the fetch API call inside a createAsyncThunk


I am trying to fetch inside a createAsyncThunk but the fetch is not being triggered even though the same code structure was used in another createAsyncThunk and fetch worked well. When I console.log(action) inside the extraReducer it throws this message:

error:
message: "[Immer] Immer only supports setting array indices and the 'length' property"
name: "Error"
stack: "Error: [Immer] Immer only supports setting array indices and the 'length' property↵    at t (http://localhost:3001/static/js/0.chunk.js:2362:11)↵    at Object.push../node_modules/@reduxjs/toolkit/node_modules/immer/dist/immer.esm.js.et.set (http://localhost:3001/static/js/0.chunk.js:3282:59)↵    at create-comment/pending (http://localhost:3001/static/js/main.chunk.js:3604:29)↵    at http://localhost:3001/static/js/0.chunk.js:1272:20↵    at e.i.produce (http://localhost:3001/static/js/0.chunk.js:3317:13)↵    at http://localhost:3001/static/js/0.chunk.js:1271:71↵    at Array.reduce (<anonymous>)↵    at http://localhost:3001/static/js/0.chunk.js:1238:25↵    at combination (http://localhost:3001/static/js/0.chunk.js:45726:29)↵    at p (<anonymous>:1:36402)↵    at v (<anonymous>:1:36684)↵    at <anonymous>:1:40069↵    at Object.dispatch (http://localhost:3001/static/js/0.chunk.js:45479:22)↵    at e (<anonymous>:1:40553)↵    at http://localhost:3001/static/js/0.chunk.js:946:22↵    at http://localhost:3001/static/js/0.chunk.js:45239:16↵    at http://localhost:3001/static/js/0.chunk.js:798:32↵    at dispatch (http://localhost:3001/static/js/0.chunk.js:45906:28)↵    at http://localhost:3001/static/js/0.chunk.js:2042:13↵    at _catch (http://localhost:3001/static/js/0.chunk.js:1834:18)↵    at http://localhost:3001/static/js/0.chunk.js:2029:24↵    at http://localhost:3001/static/js/0.chunk.js:2069:8↵    at http://localhost:3001/static/js/0.chunk.js:45236:18↵    at Object.dispatch (http://localhost:3001/static/js/0.chunk.js:798:32)↵    at dispatch (<anonymous>:1:28545)↵    at sendToApiComment (http://localhost:3001/static/js/main.chunk.js:1597:29)↵    at sendNewComment (http://localhost:3001/static/js/main.chunk.js:1210:11)↵    at HTMLUnknownElement.callCallback (http://localhost:3001/static/js/0.chunk.js:13360:18)↵    at Object.invokeGuardedCallbackDev (http://localhost:3001/static/js/0.chunk.js:13409:20)↵    at invokeGuardedCallback (http://localhost:3001/static/js/0.chunk.js:13469:35)↵    at invokeGuardedCallbackAndCatchFirstError (http://localhost:3001/static/js/0.chunk.js:13484:29)↵    at executeDispatch (http://localhost:3001/static/js/0.chunk.js:17719:7)↵    at processDispatchQueueItemsInOrder (http://localhost:3001/static/js/0.chunk.js:17751:11)↵    at processDispatchQueue (http://localhost:3001/static/js/0.chunk.js:17764:9)↵    at dispatchEventsForPlugins (http://localhost:3001/static/js/0.chunk.js:17775:7)↵    at http://localhost:3001/static/js/0.chunk.js:17986:16↵    at batchedEventUpdates$1 (http://localhost:3001/static/js/0.chunk.js:31671:16)↵    at batchedEventUpdates (http://localhost:3001/static/js/0.chunk.js:13158:16)↵    at dispatchEventForPluginEventSystem (http://localhost:3001/static/js/0.chunk.js:17985:7)↵    at attemptToDispatchEvent (http://localhost:3001/static/js/0.chunk.js:15468:7)↵    at dispatchEvent (http://localhost:3001/static/js/0.chunk.js:15386:23)↵    at unstable_runWithPriority (http://localhost:3001/static/js/0.chunk.js:47163:16)↵    at runWithPriority$1 (http://localhost:3001/static/js/0.chunk.js:20766:14)↵    at discreteUpdates$1 (http://localhost:3001/static/js/0.chunk.js:31688:18)↵    at discreteUpdates (http://localhost:3001/static/js/0.chunk.js:13170:16)↵    at dispatchDiscreteEvent (http://localhost:3001/static/js/0.chunk.js:15352:7)"
__proto__: Object
meta: {arg: {…}, requestId: "UjmyfmxeslFCy4C4FPSzc", rejectedWithValue: false, requestStatus: "rejected", aborted: false, …}
payload: undefined
type: "create-comment/rejected"

This is how the createAsyncThunk is written:

const initCreator = (verb, data = null) => {
  let result;
  if (data) {
    result = {
      method: verb,
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
      },
      redirect: 'follow',
      referrerPolicy: 'no-referrer',
      body: JSON.stringify(data),
    };
  } else {
    result = {
      method: verb,
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
      },
      redirect: 'follow',
      referrerPolicy: 'no-referrer',
    };
  }
  return result;
};    

const createComment = createAsyncThunk('create-comment', async data => {
      const init = initCreator('POST', data.item);
      const response = await fetch(`${URL}comments`, init)
        .then(data => data.json())
        .catch(error => error.json());
      return { reduxId: data.reduxId, response };
    });

And this is the comments createSlice part:

const initialState = {
  comments: [],
  error: null,
  status: 'idle',
};
const comments = createSlice({
  name: 'comments',
  initialState,
  reducers: {
    removeErrorComments: state => { state.error = null; },
  },
  extraReducers: {
    [retrieveComments.pending]: state => { state.status = 'pending'; },
    [retrieveComments.fulfilled]: (state, action) => {
      console.log(action.payload.response);
      // some code that is commented out
    },
    [retrieveComments.rejected]: (state, action) => {
      state.status = 'failed retrieve';
      state.error = action.payload;
    },
    [createComment.pending]: state => { state.comments.status = 'pending'; },
    [createComment.fulfilled]: (state, action) => {
      console.log(state, action);
     // some code that is commented out
    },
    [createComment.rejected]: (state, action) => {
      console.log(action);
      state.status = 'Failed creation comment, rejected action';
      state.error = `Something went wrong, please notify us with this error: ${action.payload}`;
    },
  },
});

After the thunk is triggered this is shown in the Redux Store:

comments(pin): []
error(pin):"Something went wrong, please notify us with this error: undefined"
status(pin):"Failed creation comment, rejected action"

What I am trying to understand is why the fetch is not being triggered, what am I doing wrong? Thanks in advance for any help provided.


Solution

  • The case which is causing that error is this one:

    [createComment.pending]: state => { state.comments.status = 'pending'; },
    

    state here refers to the state for this slice, so state.comments is an array. When you try to set the property status on an array, you get an error about how only certain properties of arrays are allowed.

    You want to be setting state.status instead.

    [createComment.pending]: state => { state.status = 'pending'; },
    

    There is an unrelated typescript error when setting state.error since the initial value is null. You need to define a type for your state which allow error to be null but also allows other values.