Live Search for News Api call - React Hooks, JavaScript

Hi,
I have a react app making api news call with axios. I am trying to add a live search feature, to search the data I have already fetched.

Site and components are already built, I just cant figure out how to live search the data… I have looked at tutorials, but usually the entire app is on one component, while mine is broken up in different components. I tried to reverse engineer other people live search code, but still no luck… would love it if someone can help me find a solution.

Search.js file:

const Search = ( {props} ) =>{
  const [searchValue, setSearchValue] = useState("");
  const handleSearchInputChange =(e) => {
    setSearchValue(e.target.value);
  }
  const resetInputField = () => {
    setSearchValue("")
  }
  const callSearchFunction = (e) => {
    e.preventDefault();
    props.search(searchValue);
    resetInputField(); 
  }

  return (
      <form className="search">
        <input
          value={searchValue} 
          onChange={handleSearchInputChange}
          type="text"
          placeholder="Search News..."
        />
        <i class="fas fa-search" onClick={callSearchFunction} type="submit" value="SEARCH"></i>
      </form>
    );
}
export default Search;

TopBar.js file

function TopbarContainer() {
  const [news, setNews] = useState([]);
  useEffect(() => {
    getNews3().then(data => setNews(data));/
  }, []);

  return(
    <div className="topbar">
      <h2>AI News</h2>
      <Search />
      <div className="topbar-flex">
      {news.map((data, index) => <Topbar key={index} props={data} />)}
      </div>
    </div>
  )
}

export default TopbarContainer

link to site: https://tech-news-for-geeks.netlify.com/
link to gh: https://github.com/ainneo/tech-news-api/tree/master/src

I think we might need to know how you are planing to use the search. The simplest solution is likely to move the state up and pass it down (Lifting State Up).

BTW, instead of having three fetch functions with just the URL being different I would suggest you unify the function. For example, make it take an argument that will set what URL to use.

I am trying to live search for news articles based on title. I am not sure how to implement that into the code…

I have 5 components…
3 of which are cards that fetch the data.

  • 1 is for Tech news
  • 2 AI news
  • 3 News from NewAPI.

I am only trying to create a search function by article title for the AI news.
I guess I am super confused on how to do that…
I have done 3 tutorials off youtube on live search feed, but they were all in one component …

I can create a search in basic JS and HTML, but in react it’s not working and I am not sure how to implement the data.

you can do this by passing a callback function to the parent component which is TopbarContainer and then it have it filter the news array from there, so for example lets call it searchHandler so first you want to move your state from search component to the topbarContainer
const [searchValue, setSearchValue] = useState("");

then create a function that updates it

const searchHandler = (value) => {
    setSearchValue(value) 
  }

add this function onto your search component the same as a prop

<Search searchHandler={searchHandler}/>

then create a filter that will filter the news by what is in the state

let updateNews = news.filter((article) => {
  return article.title.toLowerCase().includes(searchValue)
})

now change the news.map() to updateNews.map()

  {updateNews.map((lemons, index) => <Topbar key={index} props={lemons} />)}

now all you have to do is call the function from search.js component which is passed through like a prop

const Search = ( { searchHandler } ) =>{
 
  const handleSearchInputChange =(e) => {
    searchHandler(e.target.value);
  }

this will call the function on every keypress and update your state on the TopbarContainer
here is full code just so you better idea of what i mean :slightly_smiling_face:

Search.js

const Search = ( { searchHandler } ) =>{
 
  const handleSearchInputChange =(e) => {
    searchHandler(e.target.value);
  }

  return (
      <form className="search">
        <input
          onChange={handleSearchInputChange}
          type="text"
          placeholder="Search News..."
        />
        <i class="fas fa-search"  type="submit" value="SEARCH"></i>
      </form>
    );
}

TopbarContainer.js

function TopbarContainer() {
  const [searchValue, setSearchValue] = useState("");
  const [news, setNews] = useState([]);

  useEffect(() => {
    getNews3().then(data => setNews(data));
  }, []);


  const searchHandler = (value) => {
    setSearchValue(value) 
  } 

let updateNews = news.filter((article) => {
  return article.title.toLowerCase().includes(searchValue)
})


  return(
    <div className="topbar">
      <h2>AI News</h2>
      <Search searchHandler={searchHandler}/>
      <div className="topbar-flex">
      {updateNews.map((lemons, index) => <Topbar key={index} props={lemons} />)}
      </div>
    </div>
  )
}
2 Likes

Thank you so much! You saved me so much headache… I wish there was a way to tip in crypto… if you have a github or twitter set up to receive BAT tokens as a tip, let me know… I would totally tip you in BAT.

@freeCodeCamp
I already tip FreeCodeCamp most of my BAT tokens… Maybe they should aloud users to tip other users in BAT too?

2 Likes

glad to help, no need for tip :slightly_smiling_face:

1 Like