Reputation: 29
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
Upvotes: 0
Views: 2198
Reputation: 1259
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!
Upvotes: 0
Reputation: 167240
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;
Upvotes: 1