I have a section of code in my react app that calls an API that returns the capital city of an input country. In order to output the country with correct capitalisation, I have a function gets the country name from the API as well. When I omit the bit that gets the country name, it works perfectly, but when it is included I get the aforementioned error, most of the time. Sometimes when I alter the code slightly, I don't get the error and it works fine until I refresh the webpage, at which point it breaks again.

function SearchButton() {
  async function GetCountryName(countryInput) { //Gets correctly capitalised country name
    const response = await fetch(`https://restcountries.com/v3.1/name/${countryInput}?fields=name`);
    const text = await response.text();
    let countryOutput = text.split('\",\"')[0]; //Removes superfluous characters after name
    countryOutput = countryOutput.split('\":\"')[1]; //Removes superfluous characters before name
    console.log(countryOutput);
    return countryOutput;
  }

  const displayResult = document.getElementById("output"); //Gets output location

  async function handleClick() { //Searches in API for the country in the textbox
    const countryInput = document.getElementById("Country").value.toLowerCase(); //Gets input
    if (countryInput){
      const response = await fetch(`https://restcountries.com/v3.1/name/${countryInput}?fields=capital`); //Finds capital
      const text = await response.text();
      
      const countryOutput = await GetCountryName(countryInput);

      if (!text.includes("capital")) { //If there is not a valid output for the input
        displayResult.innerHTML = `Please enter a country.`;
      } else {
        const textOut = text.split('\"]')[0]; //Removes superfluous characters after capital
        const textFinal = textOut.split('[\"')[1]; //Removes superfluous characters before capital
        console.log(countryOutput);
        console.log(textFinal);
        displayResult.innerHTML = `The capital of ${countryOutput} is ${textFinal}`;
      }
    } else { //If clicked without search term
      displayResult.innerHTML = `Please enter a country.`;
    }
  }

  return (
    <button type="button" id="SearchButton" onClick={handleClick}>
    Search
    </button>);
}

The console logs show that the outputs both exist.

1

There are 1 best solutions below

0
ALTHAF P JALEEL On

Here you are writing to the displayResult variable when your component is rendered. Depending on the way that you are using this component, the dom element with id=output might not yet be available when you query it and hence it could be null. Later when you click the button, handleClick function will throw the error that you are getting, since displayResult is null.

So moving the line

const displayResult = document.getElementById("output"); //Gets output location

to inside the handleClick function should fix this issue for you, since by then that output element will be available in DOM

Having said all of the above, I have couple of suggestions for you

  1. It is not a good approach to set innerHTML directly if you are using a react application. You can keep a state variable to which you can assign the result from API, and can render it inside the output div.
  2. You can use Promise.all to make the two API calls in parallel