0

I am new to React and I want to run API based search. I have written a sample code with the search functionality but it is not working as per requirement. I want to search from the list but it is always giving the same array of as the whole list when I am writing anything in the search box. Please help me out and let me know where the code in wrong. Here is my code:

TestEntry.js

import React , {useState,useEffect} from  'react'
import {Table} from 'reactstrap'
import {Navbar,Nav,NavDropdown,Form,FormControl,Button} from 'react-bootstrap'
//import axios from 'axios'
import Loading from './loading.gif';


const CoinGecko = require('coingecko-api');
const CoinGeckoClient = new CoinGecko();
function TestEntry(){


const[item,SearchData]=useState([]);
const[cryptos,setCryptos]=useState([]);

useEffect(()=>{
    fetchItems()
},[])

const fetchItems=async()=>{
    const url="https://api.coingecko.com/api/v3/coins/list";
    const response= await fetch(url);
    const info=await response.json();
    console.log(info);
    setCryptos(info);
}


const Search=(key)=>{
    console.log(key);
    fetch("https://api.coingecko.com/api/v3/coins/list?q="+key)
    .then((data)=>{
        data.json().then((resp)=>{
            console.warn("resp:",resp)
            SearchData(resp)
        }) 
    })

}

const cryptoJsx=cryptos.map(crypto=>(
    <div key={crypto.id}>
            {crypto.id}
    </div>
));

        return(
            <div>
                Search:
                <input type="text" onChange={(event)=>Search(event.target.value)}/>
                <div>
                    {
                        {item} ? 
                        <div>
                            {
                                item.map((items)=>
                                <div key={items.id}>{items.name}</div>
                                )
                            }

                        </div>
                        :  ""
                    }
                </div>
                        {cryptoJsx}


            </div>
        )

}

export default TestEntry
ishani pathak
  • 13
  • 1
  • 4

1 Answers1

0

The search api seems not working. When I tried api-search for a text separately in browser, it returned full results.

Anyway....

You can do search locally i.e. filter the cryptos array. It will cause re-render and only filtered results are shown. Note:

  • Maintain a copy of the cryptos and always filter based on original and only mutate the cryptos. This way search works (both typing a char and deleting a char) and search results are re-rendered automatically
  • The downside of filtering state data is that new data from server is only obtained in client upon page refresh
  • If you really want to use api docs and use correct endpoint. Also consider using debouncing. Perform debounce in React.js

I have checked this and search is working fine.

import React, { useState, useEffect } from "react";

function TestEntry() {
  const [item, SearchData] = useState([]);
  const [cryptos, setCryptos] = useState([]);
  const [origCryptosCount, setOrigCryptosCount] = useState([]);

  useEffect(() => {
    fetchItems();
  }, []);

  const fetchItems = async () => {
    const url = "https://api.coingecko.com/api/v3/coins/list";
    const response = await fetch(url);
    const info = await response.json();
    setCryptos(info);
    setOrigCryptosCount(info);
  };

  // const Search_Old = key => {
  //   console.log(key);
  //   fetch("https://api.coingecko.com/api/v3/coins/list?q=" + key).then(data => {
  //     data.json().then(resp => {
  //       SearchData(resp);
  //     });
  //   });
  // };
  //
  const Search = key => {
    const newResults = origCryptosCount.filter(crypto => crypto.name.includes(key));
    console.log('newResults', newResults);
    setCryptos(newResults);
  };

  const cryptoJsx = cryptos.map(crypto => (
    <div key={crypto.id}>{crypto.id}</div>
  ));

  return (
    <div>
      Search:
      <input type="text" onChange={event => Search(event.target.value)} />
      {cryptoJsx}
    </div>
  );
}

export default TestEntry;

gdh
  • 13,114
  • 2
  • 16
  • 28
  • What if I had to do live search? – ishani pathak Apr 07 '20 at 14:11
  • Apparently, there is no CoinGecko endpoint to support searching coin list by name. It means that you have to fetch data and filter data every time in live search. – Kelvin Apr 07 '20 at 14:20
  • the problem is the search-api. `https://api.coingecko.com/api/v3/coins/list?q=coin` ... Whatever you search it gives you full result and hence renders everything.... assuming your search-api returned full results, then in my answer use the commented Search fun..it should work...and no need to use your `{item} ? ... item.map` piece of code ... because in the initial render you are getting full list .... and in search onChange you will get filtered data from the server and ui is re-rendered automatically... just make sure the search api is all good... any further issues , reply – gdh Apr 07 '20 at 14:22
  • @gdh "The search api seems not working" is false. There is no problem with it. Api works as specified in [documentation](https://www.coingecko.com/en/api). – Danko Apr 07 '20 at 15:02
  • @Danko I actually didn't mean that the API itself is not working.... what i meant was the search endpoint `https:......list?q=coin` is not working ... if you read my previous comment, it is clear .... Also you have mentioned this pretty much same in your 1st comment to the question ... My answer and comment helps local search as well as live search which i believe has helped the person who asked the question... – gdh Apr 07 '20 at 21:12
  • @gdh the code works perfectly with your specified changes. Thank you so much. – ishani pathak Apr 08 '20 at 12:16