mura1
mura1

Reputation: 472

Search functionality in React

so the problem is I have a search functionality everything works, except that when an item has not been found, you see it should display the text "champion has not been found" but it is not. I would appreciate the help Where am I making a mistake?

import data from './data.json'
import  './Champions.css'
import Skills from './Skills'
import CloseIcon from '@material-ui/icons/Close';



const Champions = ({searchValue}) => {
  const [toggleShow, setToggleShow] = useState(false);
  const [currentSelectedChampion, setCurrentSelectedChampion] = useState({});


  const handleSelectChampion = (id) => {
    if (!toggleShow) setToggleShow(true);
    const currentChampion = data.filter((champ) => champ.id === id)[0];
    setCurrentSelectedChampion(currentChampion);

  };


  function filterChampions(champion) {
    return champion.name.toLowerCase().includes(searchValue.toLowerCase());
  }

{data.filter(filterChampions).length === 0 && (<div className='not__found'>
          <h1>No champion has been found</h1>
        </div>)}

  return (
    <div className="champions">
    {data.filter(filterChampions).map((champion) => {
        return (
          <div key={champion.id} onClick={() => handleSelectChampion(champion.id) } >     
            <div className="champion">
              <img className="champion__Image" src={champion.image}></img>
              
              <h4 className="champion__Name">{champion.name}</h4>        
              {toggleShow && currentSelectedChampion.id === champion.id && (                
                <>
                  <Skills currentChampion={currentSelectedChampion} />
                    <CloseIcon onClick={() => setToggleShow(false)}/>              
                </>
              )}
             </div>
          </div>     
        );
      })}
         
    </div>
  );
};

export default Champions

Upvotes: 1

Views: 105

Answers (2)

Darshna Rekha
Darshna Rekha

Reputation: 1116

The map in line {data.filter(filterChampions).map((champion) => { will not return anything for empty array.

Consider the following examples.

[].map(e => 'called'); // []

[3].map(e => 'called'); // ['called']

So if {data.filter(filterChampions) returns an empty array the map will return empty array and not the div with class not__found.

What you need to do is something as following

  const showChamtions = () => {
    // Put the filtered data in a variable
    const selectedChampions = champions.filter((element) => element.score > 12);

    // If data is there do what you intend to do with it else not_found div

    if (selectedChampions && selectedChampions.length > 0) {
      return selectedChampions.map((element) => <p>{element.name}</p>);
    } else {
      return (
        <div className="not__found">
          <h1>No champion has been found</h1>
        </div>
      );
    }
  };

Example - https://codesandbox.io/s/map-on-empty-array-i6m1l?file=/src/App.js:349-741

You can modify your code similar to this using a conditional operator as well.

Upvotes: 3

Co Pham
Co Pham

Reputation: 361

{data.filter(filterChampions).map((champion) => {
      if(data.filter || champion){
        return (
        <div className='not__found'>
          <h1>No champion has been found</h1>
        </div>
        )
      }

This if statement is not nesserasy, if an item has not been found => data.filter(filterChampions) will be an empty array, the map function will return nothing, the if statement doesn't even run.
It you want to display the message, you could simply use this:

{data.filter(filterChampions).length === 0 && (<div className='not__found'>
          <h1>No champion has been found</h1>
        </div>)}

Upvotes: 1

Related Questions