Hubert Spychala
Hubert Spychala

Reputation: 23

TypeError: Cannot read properties of undefined (reading 'find') ReactJS

Can anyone help me with my problem? Im a beginner and im trying to build a small blog app in React.

I'm getting the error, "TypeError: Cannot read properties of undefined (reading 'find')" which points to the block of code in PostPage.js:

  const { id } = useParams();
  const post = posts.find((post) => post.id.toString() === id);

Here's full PostPage.js code:


const PostPage = ({ posts, handleDelete }) => {
  const { id } = useParams();
  const post = posts.find((post) => post.id.toString() === id);
  return (
    <main className="PostPage">
      <article className="post">
        {post && (
          <>
            <h2>{post.title}</h2>
            <p className="postDate">{post.datetime}</p>
            <p className="postBody">{post.body}</p>
            <button onClick={() => handleDelete(post.id)}>Delete Post</button>
          </>
        )}
        {!post && (
          <>
            <h2>Post Not Found</h2>
            <p>Well, that's disappointing.</p>
            <p>
              <Link to="/">Visit Our Homepage</Link>
            </p>
          </>
        )}
      </article>
    </main>
  );
};
export default PostPage;

Post.js


const Post = ({ post }) => {
  return (
    <article className="post">
      <Link to={`/post/${post.id}`}>
        <h2>{post.title}</h2>
        <p className="postDate">{post.datetime}</p>
      </Link>
      <p className="postBody">
        {post.body.length <= 25 ? post.body : `${post.body.slice(0, 25)}...`}
      </p>
    </article>
  );
};

export default Post;

App.js:

import Header from "./Header";
import Nav from "./Nav";
import Footer from "./Footer";
import Home from "./Home";
import NewPost from "./NewPost";
import PostPage from "./PostPage";
import About from "./About";
import Missing from "./Missing";
import { Route, Switch, useHistory } from "react-router-dom";
import { useState, useEffect } from "react";

function App() {
  const [posts, setPosts] = useState([
    {
      id: 1,
      title: "My First Post",
      datetime: "July 01, 2021 11:17:36 AM",
      body: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis consequatur expedita, assumenda similique non optio! Modi nesciunt excepturi corrupti atque blanditiis quo nobis, non optio quae possimus illum exercitationem ipsa!",
    },
    {
      id: 2,
      title: "My 2nd Post",
      datetime: "July 01, 2021 11:17:36 AM",
      body: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis consequatur expedita, assumenda similique non optio! Modi nesciunt excepturi corrupti atque blanditiis quo nobis, non optio quae possimus illum exercitationem ipsa!",
    },
    {
      id: 3,
      title: "My 3rd Post",
      datetime: "July 01, 2021 11:17:36 AM",
      body: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis consequatur expedita, assumenda similique non optio! Modi nesciunt excepturi corrupti atque blanditiis quo nobis, non optio quae possimus illum exercitationem ipsa!",
    },
    {
      id: 4,
      title: "My Fourth Post",
      datetime: "July 01, 2021 11:17:36 AM",
      body: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis consequatur expedita, assumenda similique non optio! Modi nesciunt excepturi corrupti atque blanditiis quo nobis, non optio quae possimus illum exercitationem ipsa!",
    },
  ]);
  const [search, setSearch] = useState("");
  // const [searchResults, setsearchResults] = useState([]);
  const handleDelete = (id) => {};

  return (
    <div className="App">
      <Header title="React JS Blog" />
      <Nav search={search} setSearch={setSearch} />
      <Switch>
        <Route exact path="/">
          <Home posts={posts} setPosts={setPosts} />
        </Route>
        <Route exact path="/post">
          <NewPost />
        </Route>
        <Route path="/post/:id">
          <PostPage post={posts} handleDelete={handleDelete} />
        </Route>
        <Route path="/about" component={About} />
        <Route path="*" component={Missing} />
      </Switch>
      <Footer />
    </div>
  );
}

export default App;

I will be grateful for your help

Upvotes: 2

Views: 2080

Answers (3)

Sacredice
Sacredice

Reputation: 1

Problem is in App.js line 55.

<PostPage post={posts} handleDelete={handleDelete} />

post={posts} change this with => posts={posts}

<PostPage posts={posts} handleDelete={handleDelete} />

In PostPage.js you simply try to destructure posts that are undefined and undefined.find() code crashes.

Upvotes: 0

Nikhil Pathania
Nikhil Pathania

Reputation: 831

Make posts to [] in the default case. That's it!

const PostPage = ({ posts = [], handleDelete }) => {
  const { id } = useParams();
  const post = posts.find((post) => post.id.toString() === id);
  return (
    <main className="PostPage">
      <article className="post">
        {post && (
          <>
            <h2>{post.title}</h2>
            <p className="postDate">{post.datetime}</p>
            <p className="postBody">{post.body}</p>
            <button onClick={() => handleDelete(post.id)}>Delete Post</button>
          </>
        )}
        {!post && (
          <>
            <h2>Post Not Found</h2>
            <p>Well, that's disappointing.</p>
            <p>
              <Link to="/">Visit Our Homepage</Link>
            </p>
          </>
        )}
      </article>
    </main>
  );
};
export default PostPage;

Upvotes: 2

Shubham Kumar
Shubham Kumar

Reputation: 596

The main problem here is: PostPage component is not receiving posts as a prop from its parent component. To confirm this you can add a console.log:

const PostPage = ({ posts, handleDelete }) => {
  const { id } = useParams();
  console.log(posts)
  const post = posts.find((post) => post.id.toString() === id);
  // ..... rest of the code

Now as to handle posts defined / undefined you can use ?. operator :

const PostPage = ({ posts, handleDelete }) => {
  const { id } = useParams();
  const post = posts?.find((post) => post.id.toString() === id);
  // ..... rest of the code

I would suggest to shift to typescript to prevent these kind of errors in future.

Upvotes: 0

Related Questions