0

I'm trying to fetch from my backend database (MongoDB) on my localhost to display all blogposts.

I'm assuming I need to iterate through each blogpost on the frontend. Right now, only "Author" and "Comments" display, but with no actual data.

What would that syntax look like?

Here's what the React page looks like where I'm fetching and displaying.

import React, { Component } from 'react'

class Blog extends Component {
    constructor() {
        super()
    
        this.state = {
          blogPost: [],
          finishedLoading: true
        }
      }    
    
    async componentDidMount() {    
        const response = await fetch('http://localhost:8000/api/blogPosts/all')
        const json = await response.json()
        this.setState({ blogPost: json.blogPosts, finishedLoading: false })
      }
    
    reload = async () => {
        const response = await fetch('http://localhost:8000/api/blogPosts/all')
        const json = await response.json()
        this.setState({ blogPost: json.blogPosts, finishedLoading: true })
      }
    
    render() {
        
    if (this.state.blogPost.length === 0) {
        return (
          <div className="App">
            <h1>No blogposts have been posted!</h1>
          </div>
        )
    }
   

    return (
            <div class="blogPost">
                <h2>{this.state.blogPost.title}</h2>
                <p> Author: {this.state.blogPost.author}</p>
                <p>{this.state.blogPost.content}</p>
                <p>Comments:</p>

                <ul>
                
                </ul>
            </div>
        )
    }
}

export default Blog
3
  • What's the question??? Commented Dec 22, 2020 at 20:17
  • @RuanDuarte Question's clear... There's a huge mistake in the author's side, which is common with new developers. Commented Dec 22, 2020 at 20:22
  • 1
    Yeah, I tried to check the answer, but there was a certain amount of time that had to pass before I could do that. Commented Dec 22, 2020 at 21:32

2 Answers 2

1

You're supposed to iterate through the contents but you're doing only once, that too on an array:

return (
  <div class="blogPost">
    <h2>{this.state.blogPost.title}</h2>
    <p> Author: {this.state.blogPost.author}</p>
    <p>{this.state.blogPost.content}</p>
    <p>Comments:</p>

    <ul></ul>
  </div>
);

The above code is wrong. What you need to do is iterate the contents of this.state.blogPost, which is an array of blog objects:

return this.state.blogPost.map((blog, key) => (
  <div class="blogPost" key={key}>
    <h2>{blog.title}</h2>
    <p> Author: {blog.author}</p>
    <p>{blog.content}</p>
    <p>Comments:</p>
    <ul></ul>
  </div>
));

You might need to do the same thing to fetch the comments too. Say, the comments are an array of comments in the object, then do this:

return this.state.blogPost.map((blog, key) => (
  <div class="blogPost" key={key}>
    <h2>{blog.title}</h2>
    <p> Author: {blog.author}</p>
    <p>{blog.content}</p>
    <p>Comments:</p>
    <ul>
      {blog.comments.length > 0 ? (
        blog.comments.map((c, k) => <li key={key}>{c}</li>)
      ) : (
        <li>No comments.</li>
      )}
    </ul>
  </div>
));

Full code here:

import React, { Component } from "react";

class Blog extends Component {
  constructor() {
    super();

    this.state = {
      blogPost: [],
      finishedLoading: true
    };
  }

  async componentDidMount() {
    const response = await fetch("http://localhost:8000/api/blogPosts/all");
    const json = await response.json();
    this.setState({ blogPost: json.blogPosts, finishedLoading: false });
  }

  reload = async () => {
    const response = await fetch("http://localhost:8000/api/blogPosts/all");
    const json = await response.json();
    this.setState({ blogPost: json.blogPosts, finishedLoading: true });
  };

  render() {
    if (this.state.blogPost.length === 0) {
      return (
        <div className="App">
          <h1>No blogposts have been posted!</h1>
        </div>
      );
    }

    return this.state.blogPost.map((blog, key) => (
      <div class="blogPost" key={key}>
        <h2>{blog.title}</h2>
        <p> Author: {blog.author}</p>
        <p>{blog.content}</p>
        <p>Comments:</p>
        <ul>
          {blog.comments.length > 0 ? (
            blog.comments.map((c, k) => <li key={key}>{c}</li>)
          ) : (
            <li>No comments.</li>
          )}
        </ul>
      </div>
    ));
  }
}

export default Blog;
Sign up to request clarification or add additional context in comments.

Comments

0

You are setting this.state.blogPost to an array of blogPosts that you receive from your database. So, this.state.blogPost.author will be undefined since an array won't have a .author property. The items inside the array will have the property instead, accessed like so: this.state.blogPost[0].author to get the author of the first post.

To display a div for every item in the array, you need to loop through the array in your render function with .map:

return (
        this.state.blogPost.map((post, index) => (
            <div class="blogPost" key={index}>
                <h2>{post.title}</h2>
                <p> Author: {post.author}</p>
                <p>{post.content}</p>
                <p>Comments:</p>
                
                <ul>
                
                </ul>
            </div>
        ));
        
    )

Edit: looks like I was beat to the punch!

3 Comments

looks like I was beat to the punch! - What does this mean? 😅
@PraveenKumarPurushothaman it means you were fast and answered the question before I could, it's nothing bad
Yea, I know it was a friendly thing! Haha. Just wanted to know the context. 😁 Wait, did you not see the emoji? This one - "😅"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.