Hi, I am doing the News Reader task and for some reason the comments won’t display, instead, they are simply loading forever. I double-checked my code and watched the video and everything seems just like in the video.
Here is the code:
commentsSlice.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
export const loadCommentsForArticleId = createAsyncThunk(
"comments/loadCommentsForArticleId",
async (articleId) => {
const response = await fetch(`api/articles/${articleId}/comments`);
const json = await response.json();
return json;
}
);
export const postCommentForArticleId = createAsyncThunk(
'comments/postCommentForArticleId', async ({
articleId, comment}) => {
const requestBody = JSON.stringify({
comment: comment
});
const data = fetch(`api/articles/${articleId}/comments`, {
method: "POST",
body: requestBody
});
const json = await data.json();
return json;
});
export const commentsSlice = createSlice({
name: 'comments',
initialState: {
byArticleId: {},
isLoadingComments: false,
failedToLoadComments: false,
createCommentIsPending: false,
failedToCreateComment: false
},
extraReducers: (builder) => {
builder.addCase
(loadCommentsForArticleId.pending,
(state) => {
state. isLoadingComments = true;
state.failedToLoadComments = false;
}).addCase(loadCommentsForArticleId.rejected,
(state) => {
state. isLoadingComments = false;
state.failedToLoadComments = true;
}).addCase(loadCommentsForArticleId.fulfilled,
(state) => {
state. isLoadingComments = false;
state.failedToLoadComments = false;
const {articleId, comments} =
action.payload;
state.byArticleId[articleId] = comments;
}).addCase(postCommentForArticleId.pending,
(state) => {
state.createCommentIsPending = true;
state.failedToCreateComment = false;
}).addCase(postCommentForArticleId.rejected,
(state) => {
state.createCommentIsPending = false;
state.failedToCreateComment = true;
}).addCase(postCommentForArticleId.fulfilled,
(state, action) => {
state.createCommentIsPending = false;
state.failedToCreateComment = false;
const { articleId } = action.payload;
state.byArticleId[articleId].push(action.payload)
});
},
});
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;
Comments.js
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
loadCommentsForArticleId,
selectComments,
isLoadingComments,
} from '../comments/commentsSlice';
import { selectCurrentArticle } from '../currentArticle/currentArticleSlice';
import CommentList from '../../components/CommentList';
import CommentForm from '../../components/CommentForm';
const Comments = () => {
const dispatch = useDispatch();
const article = useSelector(selectCurrentArticle);
// Declare additional selected data here.
const comments = useSelector(selectComments);
const commentsAreLoading = useSelector(isLoadingComments);
const commentsForArticleId = article ?
comments[article.id] : [];
if(article) {
dispatch(loadCommentsForArticleId(article.id));
}
useEffect(() => {
}, [article, dispatch])
if (commentsAreLoading) return <div>Loading Comments</div>;
if (!article) return null;
return (
<div className='comments-container'>
<h3 className='comments-title'>Comments</h3>
<CommentList comments={commentsForArticleId} />
<CommentForm articleId={article.id} />
</div>
);
};
export default Comments;
CommentList.js
import React from 'react';
import Comment from './Comment';
export default function CommentList({ comments }) {
if (comments) {
return (
<ul className='comments-list'>
{comments.map((comment) => (
<Comment comment={comment}/>
))}
</ul>
);
}
return null;
}```