'implementing search bar in api

So I am struggling with APIs and how to handle them. I am currently stuck on an error and haven't been able to figure out how to fix it. My goal with this project is to be able to use the cocktailapi and have a search bar where a user can search by an ingredient, ie gin. I get the below error when I run the code. I'm just not sure how to fix this.

Uncaught (in promise) SyntaxError: Unexpected end of JSON input at extrafile.js:25:34

I also get the below error why I type input in the search bar.

Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')extrafile.js:45 at displayIngredientResults (extrafile.js:45:26) at HTMLInputElement. (extrafile.js:18:5)

Any advice is greatly appreciated.

window.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
  });

const drinks = document.getElementById('drinks1');
const searchBar = document.getElementById('search-Bar');
let ingredientResults = [];


searchBar.addEventListener('keyup', (e) => {
    const searchString = e.target.value.toLowerCase();

    const filteredIngredients= ingredientResults.filter((drinks) => {
        return (
          drinks.strIngredient.toLowerCase().includes(searchString)
        );
    });
    displayIngredientResults(filteredIngredients);
});


const loadIngredientResults = () => {
    try {
        const res =  fetch('https://www.thecocktaildb.com/api/json/v1/1/filter.php?i='+ searchBar.value)
        .then(res => {return res.json()});
        // ingredientResults = res.JSON().results;
        // displayIngredientResults(ingredientResults);
    } catch (err) {
        console.error(err);
    }
};

const  displayIngredientResults = (results) => {
    const htmlString = results
    .map((drinks) => {
            return `
            <div class="card">
        <div class="card-body">
        <h2>${drinks.strIngredient}</h2>
        </div>
            </div>
        `;
        })
        .join('');
        drinks.innerHTML = htmlString;
};

loadIngredientResults();
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
        <link rel="stylesheet" href="styles.css" />
        <script src="searchbyingredient.js"></script>
    </head>
    <body>
        <div class="container">
            <h1>&#x2728;Cocktails &#x2728;</h1>
            <div id="searchWrapper">
                <input
                    type="text"
                    name="searchBar"
                    id="searchBar"
                    placeholder="Search for a Cocktail"
                />
            </div>
            <ul id="cocktailsList"></ul>
        </div>

        <!DOCTYPE html>
<html lang="en">
<head>

    <title>Cocktail App</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
    <link rel="stylesheet" href="styles.css">
  
</head>

    <br>
    <div class="card" style="width: 18rem;">
        <div class="card-body" id = " card">  
          <label for="site-search" ></label>
    <body>
        <div class="container2">
            <div id="searchWrapper">
                <input
                    type="text"
                    name="search-Bar"
                    id="search-Bar"
                    placeholder="Enter Main Ingredient"
                />
            </div>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
      <script src="extrafile.js"></script>
      <!-- <script src="searchbyingredient.js"></script> -->
    </body>
</html>


Solution 1:[1]

A couple issues here:

The following line sets drinks as null or undefined, since your HTML does not already contain a div with the id of "drinks1".

const drinks = document.getElementById('drinks1');

If you want to create the element in Javascript, you'll need to use a library like jQuery to help you do that like this https://api.jquery.com/add/, or use vanilla javascript like this https://www.javascripttutorial.net/dom/manipulating/create-a-dom-element/

Also, you never set the value of ingredientResults so it is always [], also the function loadIngredientResults returns a promise, and you cannot depend on ingredientResults to not be [] when you execute the following line:

const filteredIngredients= ingredientResults.filter((drinks) => {
    return (
       drinks.strIngredient.toLowerCase().includes(searchString)
    );
});

Consider creating an async/await asynchronous call on keyup and ensuring that the API call has succeeded or that filteredIngredients has a value.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 matabeitt