I have a laravelapi that fetches posts from the database and another one that fetches upvotes. Now I want to display posts on my react component and show the length of upvotes for every particular post.
Here is how I have tried it out. But im getting the value as undefined on the console. Please help. Here is my code
import React, { useState, useEffect } from 'react';
import { useNavigate } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar"
import PostSkeleton from '../../components/skeleton/PostSkeleton';
import PostWidget from '../../components/widgets/PostWidget';
import axios from 'axios';
function Community() {
let navigate = useNavigate();
const [posts, setPosts] = useState([]);
const [upvotes, setUpvotes] = useState([]);
const [limit, setLimit] = useState(4);
const [isLoading, setIsLoading] = useState(true);
const [loading, setLoading] = useState(false);
function handleClick() {
navigate("/add-post");
}
useEffect(() => {
let isMounted = true;
axios.get(`/api/posts?page=1&limit=` limit).then(res => {
if (isMounted) {
if (res.data.status === 200) {
setPosts(res.data.posts);
setIsLoading(false);
setLoading(false);
}
}
});
return () => {
isMounted = false
};
}, [limit]);
const loadMore = () => {
setLimit(limit 4)
setLoading(true);
}
useEffect(() => {
let isMounted = true;
axios.get(`/api/upvotes`).then(res => {
if (isMounted) {
if (res.data.status === 200) {
setUpvotes(res.data.upvotes);
}
}
});
return () => {
isMounted = false
};
}, []);
return (
<div>
<Menubar />
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-angle-left"></i> </a>
</div>
<div className="pageTitle">Community</div>
<div className="right">
<a href="#" className="headerButton">
<i className="fi fi-rr-paper-plane"></i> </a>
</div>
</div>
<div id="appCapsule">
<div className="section">
<div className="post-input mt-3">
<form>
<a href="profile.php" className="btn btn-icon btn-secondary rounded mr-1" >
<img src="assets/img/sample/avatar/avatar4.jpg" alt="avatar" className="avatar imaged rounded" />
</a>
<div className="form-group boxed">
<div className="input-wrapper">
<input type="text" onClick={handleClick} className="form-control" placeholder="Tell the World Something" />
</div>
</div>
</form>
</div>
</div>
<div className="section mt-2 mb-3">
{isLoading && <PostSkeleton cards={4} />}
{posts.map((post) => (<PostWidget post={post} upvotes={upvotes.find(upvotes =>posts.postid === upvotes.post_id)} key={post.postid} />))}
<div className="text-center">
<a onClick={loadMore} className={limit <= posts.length ? 'btn btn-text-primary mr-1' : 'btn btn-text-primary mr-1 disabled'} >{loading ? <><span className="spinner-border spinner-border-sm mr-05" role="status" aria-hidden="true"></span>Loading More</> : <>{limit <= posts.length ? <>Load More <i className="fi fi-rr-angle-small-right"></i></> : 'All Posts Loaded'} </>}</a>
</div>
</div>
</div>
</div>
);
}
export default Community;
The PostWidget
Component
import React, { useState, useEffect } from 'react';
import { Link } from "react-router-dom";
import { LazyLoadImage } from "react-lazy-load-image-component";
import axios from 'axios';
import toast, { Toaster } from 'react-hot-toast';
const PostWidget = ( {post, upvotes}) => {
console.warn(upvotes && upvotes.length)
const formatDate = (dateString) => {
const options = { year: "numeric", month: "long", day: "numeric" }
return new Date(dateString).toLocaleDateString(undefined, options)
}
return (
<div>
<Toaster />
<div className="comment-block mb-3 pb-1">
<div className="comment-header">
<div className="avatar">
<img src="assets/img/sample/avatar/avatar1.jpg" alt="avatar" className="imaged w32 rounded mr-1" />
</div>
<div className="comment-other">
<h4 className="title">{post.user && post.user.firstname} {post.user && post.user.lastname}</h4>
<span className="time">{formatDate(post.created_at)}</span>
</div>
</div>
<div className="item">
<div className="in">
<div className="post-image mt-1">
<Link to={"/post-details/" post.postid}>
<LazyLoadImage src={`http://localhost:8000/${post.postimage}`} alt="avatar" className="imaged w-100" />
</Link>
<Link to={"/fruit-details/" post.fruit.id}>
<div className="chip mt-1 mr-1">
<span className="chip-label">{post.fruit.name}</span>
</div>
</Link>
</div>
<Link to={"/post-details/" post.postid}>
<div className="text mt-1">
{post.postcontent}
</div>
</Link>
<div className="comment-footer">
<a href="" className="comment-button">
<i className="fi fi-rr-check"></i>
Upvote (5)
</a>
<a href="" className="comment-button">
<i className="fi fi-rr-arrow-down"></i>
Downvote
</a>
<Link to={"/post-details/" post.postid} className="comment-button" >
<i className="fi fi-rr-comment"></i>
Comment
</Link>
</div>
</div>
</div>
</div>
</div>
);
}
export default PostWidget;
CodePudding user response:
upvotes={upvotes.find(upvotes =>posts.postid === upvotes.post_id)}
I think you need to use post.postId
instead of posts.postid
CodePudding user response:
This seems likely to be incorrect:
upvotes.find(upvotes =>posts.postid === upvotes.post_id)
Probably you meant to use the post
being iterated over in the predicate, not the posts
collection.
upvotes.find(upvote =>post.postid === upvote.post_id)