Filter content by typing values in a JSX input element

Filter content by typing values in a JSX input element


0

I am working on a blog project that fetches data form a graphQl api I have a defined a BlogPosts component in which the filter function should be performed

export default function Home({posts, categories}) {

  const [filteredPosts, setFilteredPosts] = useState(posts);

  const handleSearch = (filtered) => {
    setFilteredPosts(filtered);
  };
  

  return (
    <Layout categories={categories} onSearch={handleSearch}>
      <div className="mt-20">
      <main className='flex flex-col justify-center items-center h-screen pt-10 pb-30'>
          {filteredPosts?.map((post) => (
            <BlogPosts
              coverPic={post.coverPic}
              createdAt={post.createdAt}
              publishedAt={post.publishedAt}
              title={post.title}
              slug={post.slug}
              author={post.author}
              key={post.id}
            />
          ))}
        </main>
      </div>
    </Layout>
  );
}

I DO show all the available post therefore I know the data retrieves properly, but the issue is when I start typing values in Input inside of my Search component I get this error

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading ‘filter’)

and points at this line > 13 | const filteredPosts = posts.filter(
This is my Search component

export function Search({ posts, onSearch }) {
  const [searchText, setSearchText] = useState('');

  const handleInputChange = (e) => {
    const value = e.target.value;
    setSearchText(value);

    if (!value) {
      onSearch(posts);
    } else {
      const filteredPosts = posts.filter(
        (post) =>
          post.slug.toLowerCase().includes(value.toLowerCase()) ||
          post.title.toLowerCase().includes(value.toLowerCase())
      );
      onSearch(filteredPosts);
    }
  };

  return (
    <div className="flex items-center">
      <form className="flex space-x-1">
        <input
          type="text"
          className="block w-full px-4 py-2 text-purple-700 bg-white border rounded-full focus:border-purple-400 focus:ring-purple-300 focus:outline-none focus:ring focus:ring-opacity-40"
          placeholder="Search..."
          value={searchText}
          onChange={handleInputChange}
        />
      </form>
    </div>
  );
}

and the Search is imported into Layout which then is passed to Home properly

const Layout = ({ categories , posts, onSearch}) => {   

   return (
    <div>
      <nav className='flex items-center flex-wrap bg-slate-900 p-3 z-10 '>
        {/* ... navigation links ... */}
        <Search posts={posts} onSearch={onSearch} />
      </nav>
      {/* ... rest of layout ... */}
    </div>
  );
};
  

How should I modify my code so when I start typing values in the input element I retrieve the content filtered that matches the given value and stop getting the Unhandled Runtime Error error?

Share
Improve this question


Load 6 more related questions


Show fewer related questions

0

Reset to default



Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *