Unable to get data from API in JS

hi skyaparte, sorry again i’m stuck with some issues.
i’m able to pass id of selected country to the apiHolidayCal(id, year) method and i am able to print holidays for 1st option selected.

  1. Issue
let displayCountriesOptions = arr => {
  arr.forEach( ({ uuid, country_name: country, "iso-3166": alpha2Code}) => {
    let div = document.createElement('div');
    div.className = "option";
    div.innerHTML = `
    <input type="radio" class="radio" id="${uuid}" value="${alpha2Code}" name="category">
    <label class="label-text" for="${uuid}">${country}</label>
    `;
    // console.log(div);
    options_country.appendChild(div);

    //add selected country to selected box
    div.addEventListener('click', e => {
    options_cont.innerHTML = "";
      // console.log(e);
      const { target: target } = e;
      console.log(target);
      let input = target.querySelector("input"),
          label = target.querySelector("label");

    if(target.classList.contains('option')){
        console.log(`label.innerText  = ${label.innerText} and
          alpha2Code: ${input.value}`);

          selected_country.innerText = label.innerText;
          execution(input.value);
      }
      options_country.classList.remove('active');
    })
  })

In this code, I’m able to select a country only if click on the option row anywhere except that country name. If I’m adding another if to check whether I’ve clicked on the label

else if (target.classList.contains('label-text')){
   14->     console.log(`label.innerText  = ${label.innerText} and 
          alpha2Code: ${input.value}`);

          selected_country.innerText = label.innerText;
          execution(input.value);
      }

I am getting this error Cannot read property 'innerText' of null at line 14

Right Now in my codepen link no api call is being made but everything is working good in my computer. I have updated the code there and it’d be better if you copy the code in your system and then go through it

  1. Issue
//function to call all the holidays
const apiHolidayCall = (id , year) => {
  console.log(`${id} + ${year}`);
  // const [holidayVal, yearEl] = inputValidation();
  fetch(`${URL_holidays}?api_key=${APIKey}&country=${id}&year=${year}`) //${yearEl}
    .then(result => result.json())
    .then(data => {
        displayHolidaysOption(data.response.holidays);
      }).catch(err => creatingErrorDiv(`sorry cannot fetch this holiday.
         Error:${err}`));
    }

Right now once i select a country and type in a year i can’t select any other country and year without reloading the page. I believe that in displayCountriesOptions() when i am clicking on any option div its id and year value is getting passed to apiHolidayCall()
and is not getting updated when i call the other set of country and year.

  1. Issue
    Right now all of my code is going forward without me clicking on tell me button or submitting form. But i want user to click on tell me to get holiday details.
//Execution Steps
//1. allow the user to open countries options
showOptions();

//2. Give user all the option and one can be selected among them
apiCountryCall();

//3. get date value and id value and pass it to the apiHolidayCall(id, year)
const execution = id => {
  let yearsVal = 0;
  //for every keyup in years input add value to yearsVal
  yearsInt.addEventListener('keyup', e => {
  if(yearsVal !== undefined){
    yearsVal += e.target.value;
    apiHolidayCall(id, yearsVal);
  }else{
    creatingErrorDiv('Please enter the year.');
    }
  })
}

// //this function will run all the printing function which are commented right now
// form.addEventListener('submit', e => {
//   e.preventDefault();
//
//   //run execution function only when country and year is provided
//
// })


This is my execution pattern i am not able to figure out how i give user the facility to click and then know about the holiday details.
I want to call all the print functions after form submission. But right now they are being called synchronously starting from printName() in the displayHolidaysOption().

When i wrote apiCountryCall() before displayCountryOption() in order to store countries in the local storage i got this error: Uncaught ReferenceError: Cannot access 'displayCountriesOptions' before initialization
also I don’t understand how this local storage will have in not needing the repeated call to apiCountryCall() function to display countries.

It looks like you have exceeded the free API limit.

{
"meta": {
"code": 426,
"error_type": "too many requests",
"error_detail": "API Limit Exceeded. Please upgrade your account. See https://calendarific.com/ for details."
},
"response": []
}

Not sure why it is sending a 426 status code. The API docs says it should send a 429 HTTP status code.

The use of 426 Upgrade Required seems to be a misuse of that status code (and it’s missing the required Upgrade header).

426 Upgrade Required


yeah i made a new account and got a new APIkey but still i’m not able to get all the countries. I don’t know why but in my computer is working properly.
Maybe codepen has some issue as i ran the same code in JS fiddle online editor and it showed every option

You seem to be fetching on each of the year key input, that will use up the rate limit much faster. It is also concatenating all the inputs (so you end up with an invalid year).

Maybe try switching to a blur event when the user removes the focus from the year input for the holidays fetch, and maybe add some logic before the fetch to validate the input so you do not try to fetch with invalid input.

I might also suggest that you switch to an actual date input element, or at least a number input if nothing else.

hey @Iasjorg thanks for the reply but i’ve had the validation for year input but it is not working correctly .

const execution = id => {
  let yearsVal = 0;
  //for every keyup in years input add value to yearsVal
  yearsInt.addEventListener('keyup', e => {
  if(yearsVal !== undefined){
    yearsVal += e.target.value;
    apiHolidayCall(id, yearsVal);
  }else{
    creatingErrorDiv('Please enter the year.');
    }
  })
}

I want my form must run effortlessly like others form run and hence i dont want to add any blur event to restrict year input can you suggest a different method.
My biggest concern right now is 1 and 2 issue. I know what i have to do after each time entire execution finishes i.e. countdown is displayed . I want my id value may/may and my year value must definitely become empty so that i can display another chance to the user to choose a holiday, but i am not able to figure out how to code this and where should i put this part of code.

And for years and in previous year, i thought that yearsInt.innerText += e.target.value will form an year value as i am not getting another way through which i can get year typed in by the keyup event, but I am not able to clear this value for a new chance without reloading the page.

I don’t know what you mean by this? Selecting the value when the user removes focus from the input seems like as good as time as any to get the value.

const execution = id => {
  yearsInt.addEventListener('blur', e => {
    const year = e.target.value;
    apiHolidayCall(id, year);
  })
}

Again, I would suggest using a date input element and then use the change event to get the value.

const date = document.querySelector('#date')

date.addEventListener('change', (e) => {
  const date = e.target.value;
  console.log(date.substr(0, 4))
})