Home > Blockchain >  need help understanding why searchQuery.value is undefined
need help understanding why searchQuery.value is undefined

Time:08-04

so i'm currently trying to build search icon on the header clickable where you're able to search for, in this case, pokemon names, however i keep getting a console error

searchQuery.value undefined

Not sure why because the code looks valid.

Also, when you click on the search icon the icon goes above it and once you hit submit on the input it duplicates. I'm sure it's all connected the bug.

No sure why this is happening and would greatly appreciate any advice to fix this.

let pokemonRepository = (function() {
  let pokemonList = [];
  // API
  let apiUrl = "https://pokeapi.co/api/v2/pokemon/?limit=150";

  let searchIcon = $(".btn-outline-secondary");
  let modalContainer = $(".modal");
  let modalDialog = $(".modal-dialog");
  let modalContent = $(".modal-content");
  let modalBody = $(".modal-body");
  let modalTitle = $(".modal-title");
  let modalHeader = $(".modal-header");
  let modalClose = $(".btn-close");

  let listItemArray = $("li");

  function add(pokemon) {
    if (
      typeof pokemon === "object" &&
      "name" in pokemon &&
      "detailsUrl" in pokemon
    ) {
      pokemonList.push(pokemon);
    } else {
      console.error("pokemon is not correct");
    }
  }

  function getAll() {
    return pokemonList;
  }

  //  filters through pokemon names
  function search(pokemonName) {
    return pokemonList.filter((pokemon) => pokemon.name === pokemonName);
  }

  // Function adds a list of pokemon
  function addListItem(pokemon) {
    let pokemonDisplay = $(".list-group-horizontal");
    // Creates li element
    let listItem = $("<li>");
    listItem.addClass(
      "list-group-item text-center col-sm-6 col-md-4 border border-secondary bg-image img-fluid"
    );

    // Creates h1 for Pokemon Name
    let listTitle = $("<h1>");
    listTitle.html(`${pokemon.name}`);
    listTitle.addClass("display-6");

    // Creates div which holds sprites
    let listImg = $("<div>");
    loadDetails(pokemon).then(function() {
      listImg.append(
        `<img src=${pokemon.imageUrlFront} alt="${pokemon.name} sprite"/>`
      );
    });

    let listButton = $("<button>");
    listButton.text("show More");

    // Added Bootstrap Utility Class
    listButton.addClass("mp-2 btn btn-secondary");
    listButton.attr("type", "button");
    listButton.attr("data-bs-toggle", "modal");
    listButton.attr("data-bs-toggle", "#pokemonModal");

    listItem.append(listTitle);
    listItem.append(listImg);
    listItem.append(listButton);
    pokemonDisplay.append(listItem);

    buttonEvent(listButton, pokemon);
  }

  function buttonEvent(listButton, pokemon) {
    listButton.on("click", () => {
      showDetails(pokemon);
    });
  }

  function showDetails(pokemon) {
    loadDetails(pokemon).then(() => {
      // Clears existing content
      modalContainer.empty();

      modalTitle.addClass("modal-title h5 col-sml-3");

      let pokemonType = {
        fire: "text-danger",
        grass: "text-success",
        water: "text-primary",
        electric: "text-warning",
        flying: "text-info",
        poison: "text-secondary",
      };

      pokemon.types.forEach((type) =>
        modalTitle.addClass(pokemonType[type.type.name])
      );
      modalTitle.html(`${pokemon.name}`);

      modalBody.html(`
            Entry: ${pokemon.id}<br>
            Height: ${pokemon.height}<br>
            Weight: ${pokemon.weight}<br>
            Types: ${pokemon.types[0].type.name}`);

      if (pokemon.types.length === 2) {
        modalBody.innerHTML  = `, ${pokemon.types[1].type.name}`;
      }

      modalBody.innerHTML  = `<br>Abilities: ${pokemon.abilities[0]}.ability.name}`;

      if (pokemon.abilities.length === 2) {
        modalBody.innerHTML  = `, ${pokemon.abilities[1]}.ability.name}`;
      }

      modalBody.append(`<br>
          <img src=${pokemon.imageUrlFront} alt="${pokemon.name} front sprite">
          <img src=${pokemon.imageUrlBack} alt="${pokemon.name} back sprite">
          <br>
          `);

      modalDialog.append(modalContent);
      modalContent.append(modalHeader);
      modalHeader.append(modalTitle);
      modalHeader.append(modalClose);
      modalContent.append(modalBody);
      modalContainer.append(modalDialog);
    });

    modalContainer.modal("show");
  }

  modalContainer.on("shown.bs.modal", () => {
    // Jquery eventlistener
    modalClose.on("click", () => {
      modalContainer.removeClass("fade");
      modalContainer.modal("hide");
      listItemArray[0].children().click();
    });
  });

  searchIcon.on("click", () => {
    // fetching .d-flex class in form
    let bodyHeader = $(".d-flex");
    // returns the number of child elements
    if (bodyHeader.length === 1) {
      //creates input element
      let searchQuery = $("<input>");
      searchQuery.attr("placeholder", "Pokemon Name");
      searchQuery.attr("type", "search");
      searchQuery.attr("aria-label", "search Pokemon Name");
      searchQuery.addClass("form-control my-3 ps-2 col-sm");

      searchIcon.blur();
      searchQuery.focus();
      bodyHeader.append(searchQuery);

      searchQuery.on("keydown", (e) => {
        if (e.key === "Enter") {
          e.preventDefault();
          searchQuery.value =
            searchQuery.value.charAt(0).toUpperCase()  
            searchQuery.value.slice(1);

          for (let i = 0; i < listItemArray.length; i  ) {
            if (
              902 >
              listItemArray[i].children().last().getBoundingClientRect()[
                "top"
              ] &&
              listItemArray[i].children().last().getBoundingClientRect()[
                "top"
              ] > 42
            ) {
              listItemArray[i].children().last().click();
            }
          }
          for (let i = 0; i < listItemArray.length; i  ) {
            if (listItemArray[i].text().split("\n")[0] === searchQuery.value) {
              setTimeout(function() {
                listItemArray[i].children().last().click();
              }, 5);
            }
          }
        }
      });
    }
  });

  // Fetches data from API
  function loadList() {
    return fetch(apiUrl)
      .then(function(response) {
        return response.json();
      })
      .then(function(json) {
        json.results.forEach((item) => {
          let pokemon = {
            name: item.name.charAt(0).toUpperCase()   item.name.slice(1),
            detailsUrl: item.url,
          };
          add(pokemon);
        });
      })
      .catch(function(error) {
        console.error(error);
      });
  }

  function loadDetails(item) {
    let url = item.detailsUrl;
    return fetch(url)
      .then(function(response) {
        return response.json();
      })
      .then(function(details) {
        item.imageUrlFront = details.sprites.front_default;
        item.imageUrlBack = details.sprites.back_default;
        item.id = details.id;
        item.height = details.height;
        item.weight = details.weight;
        item.types = details.types;
        item.abilities = details.abilities;
      })
      .catch(function(error) {
        console.error(error);
      });
  }

  return {
    add: add,
    getAll: getAll,
    addListItem: addListItem,
    search: search,
    showDetails: showDetails,
    loadList: loadList,
    loadDetails: loadDetails,
    buttonEvent: buttonEvent,
  };
})();

pokemonRepository.loadList().then(function() {
  pokemonRepository.getAll().forEach(function(pokemon) {
    pokemonRepository.addListItem(pokemon);
  });
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="description" content="The Pokédex is a simple encyclopedia of Pokémon and their characteristics." />
  <link rel="shortcut icon" href="img/favicon.png" type="image/x-icon" />
  <title>Pokédex App</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />
  <link rel="stylesheet" href="/dist/style.production.css" />
</head>

<body>
  <nav >
    <div >
      <a href="#home" >
        <img src="img/ball.png" width="30" height="24" alt=""  /><span >Pokèdex</span>
      </a>
      <button  type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
              <span ></span>
            </button>
      <div  id="navbarSupportedContent">
        <ul >
          <li >
            <a  aria-current="page" href="#home">Home</a
                  >
                </li>
                <li >
                  <a  href="#about">About</a>
          </li>
        </ul>
        </li>
        </ul>
        <form  role="search">
          <!-- <input
                  
                  placeholder="Pokemon Name"
                  aria-label="Search"
                /> -->
          <button  type="submit">
                  <i ></i>
                </button>
        </form>
      </div>
    </div>
  </nav>

  <p ></p>
  <!-- Pokemon Display -->
  <div >
    <ul ></ul>
  </div>
  <!-- Display Ends Here -->

  <div  id="pokemonModal" tabindex="-1" role="dialog" aria-labelledby="pokemonModalLabel" aria-hidden="true">
    <div  role="document">
      <div >
        <div >
          <h5  id="pokemonModalLabel"></h5>
          <button type="button"  data-dismiss="modal" aria-label="Close" aria-hidden="true"></button>
        </div>
        <!-- Content is dynamically created using jquery -->
        <div ></div>
      </div>
    </div>
  </div>

  <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-Xe 8cL9oJa6tN/veChSP7q mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-ODmDIVzN pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK" crossorigin="anonymous"></script>

  <script src="/src/js/scripts.js"></script>

  <script src="/src/js/promise-polyfill.js"></script>
  <script src="/src/js/fetch-pollyfill.js"></script>
</body>

</html>

CodePudding user response:

Since searchQuery is a jQuery object, you need to use its .val() method to set and get the value. So change.

searchQuery.value =
searchQuery.value.charAt(0).toUpperCase()  
searchQuery.value.slice(1);

to

searchQuery.val((i, value) => value[0].toUpperCase()   value.slice(1));
  • Related