Reputation: 23
I have watched countless videos and tried to implement suggestions from here and edited the code more than I can remember. Could someone please let me know what I am doing wrong here? I am trying to get the search to go through the data and filter the cards.
The data loads fine but there are some errors in console
When I try searching, once I type anything letter. The page goes blank
And console looks like this, Cannot read properties of undefined (reading 'filter') is suggested to be an error if item received is not an array, but the results shows array.
Here is my code. I am trying to learn so I understand this is very messy and should be in components.
import React from 'react';
import { useState } from 'react';
import axios from 'axios';
import { useEffect } from 'react';
function App() {
const [data, setData] = React.useState([]);
// const [searchTerm, setSearchTerm] = React.useState('');
const [searchTerm, setSearchTerm] = useState('');
const handleChange = event => {
setSearchTerm(event.target.publications);
};
useEffect(() => {
axios.get('https://api.**url.com/api/v1/content/publications?limit=50',{
headers: {
'X-AUTH-TOKEN' : '22bc08a8***2995da615c'
}
})
.then(response => {
console.log(response.data);
setData(response.data.data);
});
}, []);
return(
<div>
<h1>Publication title goes here </h1>
{/* Search */}
<div className='App'>
<input type="text" placeholder='Search' onChange={handleChange}/>
</div>
{/* Search end*/}
<div className="px-10 py-10 grid gap-4 md:grid-cols-4">
{
data.filter((publications) =>{
if (searchTerm == "") {
return publications}
// else if (data.publications.filter(item => item.toLowerCase().includes(searchTerm.toLowerCase())))
{data.publications.filter(item => item.toLowerCase().includes(searchTerm.toLowerCase()))
{
return publications
}
}}).map(publications =>
{ return (
// card
<div className="user" key={publications.id} className="container mx-auto max-w-4xl">
<div class="max-w-sm bg-white border border-gray-200 hover:bg-gray-100 rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<img class="rounded-t-lg" src="/docs/images/blog/image-1.jpg" alt="" />
</a>
<div class="p-5">
<a href="#">
<h2 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" />
</svg>
{publications.description}</h2>
</a>
<p class="mb-3 font-normal text-gray-700 dark:text-gray-400">Author: {publications.author}.</p>
<a href="#" class="inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
Last Publication
<svg aria-hidden="true" class="w-4 h-4 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</a>
</div>
</div>
</div>
)
}
)
}
</div>
</div>
)
}
export default App;
Upvotes: 0
Views: 126
Reputation: 153
The errors are showing up in your console, because you have to use className
instead of class
in React. You are using class
in your card component. The other HTML attributes have to be written in camel case, so fill-rule
becomes fillRule
and clip-rule
becomes clipRule
.
For the issues with your filter, you should have a look at the docs for the Array.filter() and String.includes() methods. You can't filter an object with the includes method.
Also Cannot read properties of undefined (reading 'filter')
is showing up, because data.publications
IS undefined. Start using Typescript and these errors won't happen again.
Here is an example of how your filter could look like:
data.filter((publication) => {
// If no search term is set, return true
if (!searchTerm) {
return true
}
// If either the publication description or the author contain the search term, return true
if (publication.description.toLowerCase().includes(searchTerm.toLowerCase()) || publication.author.toLowerCase().includes(searchTerm.toLowerCase())) {
return true
}
// If there is a search term and neither the description nor the author contain the search term, return false
return false
})
Upvotes: 1