I got a rejection error from the redux toolkit while trying to update the item

Viewed 59

I am working on a MERN app and I have a problem when updating items. I am getting rejections when sending a patch request and there is not much info for debugging to solve the problem. I will appreciate it if someone can point out some logic that is not correct in my code. Thank you in advance. Here below is the logic I have implemented.

postService.js:

import axios from 'axios';

const API_URL = '/api/posts/';

const updatePost = async (postId, postData, token) => {
  const config = {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  };
  const response = await axios.patch(`${API_URL}/${postId}/`, postData, config);

  if (response.data) {
    return {
      ...response.data,
      id: postId,
    };
  }
};

postSlice.js:

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

const initialState = {
  posts: [],
  isError: false,
  isSuccess: false,
  isLoading: false,
  message: '',
};

export const updatePost = createAsyncThunk(
  'posts/updatePost',
  async (id, postData, thunkAPI) => {
    try {
      const token = thunkAPI.getState().auth.user.token;
      return await postService.updatePost(id, postData, token);
    } catch (error) {
      const message =
        (error.response.data.message) ||
        error.toString();
      return thunkAPI.rejectWithValue(message);
    }
  }
);

export const postSlice = createSlice({
  name: 'post',
  initialState,
  reducers: {
    reset: (state) => initialState,
  },
  extraReducers: (builder) => {
    builder
.addCase(updatePost.pending, (state) => {
        state.isLoading = true;
      })
      .addCase(updatePost.fulfilled, (state, action) => {
        state.isLoading = false;
        state.isSuccess = true;
        state.posts = state.posts.map((post) =>
          post.id === action.payload.id ? action.payload : post
        );
      })
      .addCase(updatePost.rejected, (state, action) => {
        state.isLoading = false;
        state.isError = true;
        state.message = action.payload;
      })
 });
  },
});

export const selectAllPosts = (state) => state.posts.posts;
export const { reset } = postSlice.actions;
export default postSlice.reducer;

Form.js:

const Form = ({ postId, setPostId }) => {
  const [formData, setFormData] = useState({
    postCreator: '',
    title: '',
    body: '',
    imageFile: '',
  });

  const dispatch = useDispatch();
  const user = JSON.parse(localStorage.getItem('user'));
  const post = useSelector((state) =>
    postId ? state.posts.posts.find((post) => post._id === postId) : null
  );

  useEffect(() => {
    if (post) setFormData(post);
  }, [post]);

  const clearPost = () => {
    setPostId(0);
    setFormData({
      postCreator: '',
      title: '',
      body: '',
      imageFile: '',
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (
      !formData.postCreator &&
      !formData.title &&
      !formData.body &&
      !formData.imageFile
    ) {
      toast.warning(
        'Please fill out all fields, and make sure you are also logged in'
      );
    } else if (postId) {
      dispatch(updatePost(postId, formData));
      console.log(postId);
    } else {
      dispatch(createPost(formData));
      clearPost();
      setPostId(null);
    }
    clearPost();
  };

enter image description here

1 Answers

The second param of createAsyncThunk is the payloadCreator. The first param of the payloadCreator is the arguments. The second param of payloadCreator is thunkAPI.

So you should combine id and postData into a single object to represent the arguments.

Update postSlice.js:

export const updatePost = createAsyncThunk(
  'posts/updatePost',
  async ({id, postData}, thunkAPI) => {
    try {
      const token = thunkAPI.getState().auth.user.token;
      return await postService.updatePost(id, postData, token);
    } catch (error) {
      const message =
        (error.response.data.message) ||
        error.toString();
      return thunkAPI.rejectWithValue(message);
    }
  }
);

Update where you dispatch the updatePost thunk:

updatePost({
  id: 123,
  postData: {
    foo: 'bar'
  }
})
Related