Redux News Reader

Hello, everyone I am enrolled full-stack-engineer path and in redux section right now. The project name Redux News Reader and I get stuck at step 14:

Now modify the extraReducers property of your slice configuration options by adding a reducer for each of the three promise lifecyle actions dispatched by postCommentsForArticleId :

  1. The pending promise lifecycle action
  2. The rejected promise lifecycle action
  3. The fulfilled promise lifecycle action. Note that in this case, action.payload will be a comment object including an articleId that you can use to add the comment object to correct article’s comment list in state.

Each one should update the state accordingly.

Here is my commentsSlice.js file:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; export const loadCommentsForArticleId = createAsyncThunk( 'comments/loadCommentsForArticleId', async (id, thunkAPI) => { const response = await fetch(`api/articles/${id}/comments`); const json = await response.json(); return json; } ) export const postCommentForArticleId = createAsyncThunk( 'comments/postCommentForArticleId', async ({articleId, comment}) => { const requestBody = JSON.stringify(comment); const response = await fetch(`api/article/${articleId}/comments`, { method: 'POST', body: requestBody }); const json = await response.json(); return json; } ) export const commentsSlice = createSlice({ name: 'comments', initialState: { byArticleId: {}, isLoadingComments: false, failedToLoadComments: false, createCommentIsPending: false, failedToCreateComment: false }, extraReducers: { [loadCommentsForArticleId.pending]: (state) => { state.isLoadingComments = true; state.failedToLoadComments = false; }, [loadCommentsForArticleId.fulfilled]: (state, action) => { state.isLoadingComments = false; state.failedToLoadComments = false; state.byArticleId[action.payload.articleId] = action.payload.comments; }, [loadCommentsForArticleId.rejected]: (state) => { state.isLoadingComments = false; state.failedToLoadComments = true; state.byArticleId = {}; }, [postCommentForArticleId.pending]: (state) => { state.createCommentIsPending = true; state.failedToCreateComment = false; }, [postCommentForArticleId.fulfilled]: (state, action) => { state.createCommentIsPending = false; state.failedToCreateComment = false; // I am stuck at this point }, [postCommentForArticleId.rejected]: (state) => { state.createCommentIsPending = false; state.failedToCreateComment = true; state.byArticleId = {}; } } }); export const selectComments = (state) => state.comments.byArticleId; export const isLoadingComments = (state) => state.comments.isLoadingComments; export const createCommentIsPending = (state) => state.comments.createCommentIsPending; export default commentsSlice.reducer;

Hi Đặng,

first of all, you have the initial state that is assigned an object. One of these state objects is byArticleId that is assigned another (empty) object. That is correct so far.

Then you have the extra reducers loadCommentsForArticleId for three states. The [loadCommentsForArticleId.fulfilled] fills the empty object with comments. You’ve done that correctly, are the already existing comments displayed below each article?

If that works, let’s have a look at how the byArticleId object content looks like now:
You receive a payload with an article Id and a comment. And you split it up to create a new key in the byArticleId that is equal to the article Id (state.byArticleId[action.payload.articleId]) and a value that is equal to the comment object (action.payload.comments):

byArticleId: {
  1: {//comment object},
  2: {//comment object},
  3: {//comment object},
}

Now what you need to do is adding more comment objects to the existing key value pairs in the byArticleId object.
What you get is again a payload with the article Id and a comment object that you have to split up again. You need to select the key with the article Id from the byArticleId object with bracket notation and add the new comment from the payload to the array of comments for the specific article. Either by pushing the comments to the array or by copying the existing comments with the spread syntax and adding the new comment.

I hope this helps. If not, don’t hesitate to ask.