Home > OS >  How do I connect Posts to Upvotes - ReactJS
How do I connect Posts to Upvotes - ReactJS

Time:11-13

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)
  • Related