Search code examples
javascripthtmlapifor-looponkeyup

(index):19 Uncaught ReferenceError: Search is not defined at HTMLInputElement.onkeyup


i'm making an app with marvel's api and in this app i'm trying to put a search bar but i'm not getting it.

Every time I try to search for a name in this api the function Search() it is undefined in the html.

I don't understand how the function is not defined in the html.

What can i do to change this ?

const timeStamp = "1622146184";
const privateKey = "somekey";
const publicKey = "someotherkey";
const md5 = "b34f17bceca201652c24e9aa21777da9";
const Hero = document.querySelector('article');
const input = document.getElementById('myInput');
 fetch(`http://gateway.marvel.com/v1/public/characters?ts=${timeStamp}&apikey=${publicKey}&hash=${md5}&limit=6`).then((response)=> {
    return response.json();
 }).then((jsonParsed)=>{
     jsonParsed.data.results.forEach(element => {
         const srcImage = element.thumbnail.path + '.' +  element.thumbnail.extension;
         const nameHero = element.name;
         createHero(srcImage, nameHero, Hero);
  },
  
  function Search() {
    // Declare variables
    const filter = input.value.toUpperCase();
    const textName2 = nameHero;
    // Loop through all textName2st items, and hide those who don't match the search query
    for (i = 0; i <= textName2.length; i++) {
    const p = textName2[i].getElementsByTagName("p")[0];
      txtValue = p.textContent || p.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        textName2[i].style.display = "";
      } else {
        textName2[i].style.display = "none";
      }
    } 
    })
    console.log(jsonParsed);
 })
function createHero(srcImage, nameHero, divToAppend){
    const divPai = document.createElement('section');
    const textName = document.createElement('p');
    const img = document.createElement('img');

    textName.textContent = nameHero;
    img.src= srcImage;
    divPai.appendChild(img);
    divPai.appendChild(textName);
    divToAppend.appendChild(divPai);

    divPai.classList.add("personagem");
}
<main>
    <input type="text" id="myInput" onkeyup="Search()" placeholder="Search for names.." />
    <article id="herois"></article>
</main>


Solution

  • The search function is undefined because the fetch isn't closed properly. I'm also guessing that you only want to make a request when the user has actually entered some search query. I don't see multiple article elements so don't really know what to do with this. But do note that in this case you might as well use getElementById. And if there are multiple articles with the same id that it won't work.

    const timeStamp = "1622146184";
    const privateKey = "somekey";
    const publicKey = "someotherkey";
    const md5 = "b34f17bceca201652c24e9aa21777da9";
    const Hero = document.getElementById('herois');
    const input = document.getElementById('myInput');
     
      
     async function Search() {
        console.log(input.value);
        await fetch(`http://gateway.marvel.com/v1/public/characters?ts=${timeStamp}&apikey=${publicKey}&hash=${md5}&limit=6`)
        .then( response => {
          return response.json();
       })
       .then(jsonParsed => {
          console.log(jsonParsed);
          jsonParsed.data.results.forEach(element => {
            const srcImage = element.thumbnail.path + '.' +  element.thumbnail.extension;
            const nameHero = element.name;
            createHero(srcImage, nameHero, Hero);
          });
        });
        // Declare variables
        const filter = input.value.toUpperCase();
        const textName2 = nameHero;
        // Loop through all textName2st items, and hide those who don't match the search query
        for (i = 0; i <= textName2.length; i++) {
          const p = textName2[i].getElementsByTagName("p")[0];
          txtValue = p.textContent || p.innerText;
          
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            textName2[i].style.display = "";
          } else {
            textName2[i].style.display = "none";
          }
        } 
    }
     
    function createHero(srcImage, nameHero, divToAppend){
        const divPai = document.createElement('section');
        const textName = document.createElement('p');
        const img = document.createElement('img');
    
        textName.textContent = nameHero;
        img.src= srcImage;
        divPai.appendChild(img);
        divPai.appendChild(textName);
        divToAppend.appendChild(divPai);
    
        divPai.classList.add("personagem");
    }
    <main>
        <input type="text" id="myInput" onchange="Search()" placeholder="Search for names.." />
        <article id="herois"></article>
    </main>