Hi there,
Working my way through this project and managed to got to a good place with most of it. However, after sending a POST request, I’m supposed to add the comments to the page - I’ve got it working that it will actually add an entry for the comment, but I can’t get it to show the actual text of the comment. I’ve looked in Inspector and it seems like the returned JSON doesn’t have any text in it, but it’s being sent in the body of the request, so I’m a bit lost. Could anyone help?
Below is what I believe to be relevant code:
// Import createAsyncThunk and createSlice here.
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
// Create loadCommentsForArticleId here.
export const loadCommentsForArticleId = createAsyncThunk(
'comments/loadCommentsForArticleId',
async (id) => {
const response = await fetch(`api/articles/${id}/comments`);
const json = await response.json();
return json;
}
);
// PARTICULARLY THIS BIT
export const postCommentForArticleId = createAsyncThunk('comments/postCommentForArticleId',
async ({articleId, comment}) => {
const requestBody = JSON.stringify(comment);
const response = await fetch(`api/articles/${articleId}/comments`, {
method: 'POST',
body: requestBody
});
const json = await response.json();
return json;
});
// END OF THIS BIT
export const commentsSlice = createSlice({
name: 'comments',
initialState: {
byArticleId: {},
isLoadingComments: false,
failedToLoadComments: false,
createCommentIsPending: false,
failedToCreateComment: false
},
extraReducers: {
[loadCommentsForArticleId.pending]: (state, action) => {
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, action) => {
state.isLoadingComments = false;
state.failedToLoadComment = true
},
[postCommentForArticleId.pending]: (state, action) => {
state.createCommentIsPending = true;
state.failedToCreateComment = false
},
//OR IT ALSO MIGHT BE THIS BIT
[postCommentForArticleId.fulfilled]: (state, action) => {
state.createCommentIsPending = false;
state.failedToCreateComment = false;
state.byArticleId[action.payload.articleId].push(action.payload);
},
// END OF THIS BIT
[postCommentForArticleId.rejected]: (state, action) => {
state.createCommentIsPending = false;
state.failedToCreateComment = true
},
}
});
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;
And this is the ‘CommentForm’ file, which I think is probably more likely to be OK but just in case:
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
createCommentIsPending,
postCommentForArticleId
} from '../features/comments/commentsSlice';
export default function CommentForm({ articleId }) {
const dispatch = useDispatch();
const [comment, setComment] = useState('');
// Declare isCreatePending here.
const handleSubmit = (e) => {
e.preventDefault();
dispatch(postCommentForArticleId({articleId, comment}));
setComment('');
};
return (
<form onSubmit={handleSubmit}>
<label for='comment' className='label'>
Add Comment:
</label>
<div id='input-container'>
<input
id='comment'
value={comment}
onChange={(e) => setComment(e.currentTarget.value)}
type='text'
/>
<button
className='comment-button'
>
Submit
</button>
</div>
</form>
);
}
Thanks for your time!