addEventListener behaving oddly

addEventListener behaving oddly
0

#1

Hi Campers,

While building a weather app I have run into an issue with a click listener I am trying to make. In a loop I am creating elements and filling them with data. I also want to make it so I can click on these elements and trigger a function. What happens instead is that when I press the button that initiates the loop to create these elements, that button is instead triggering the click listener, once for each iteration of the loop. I can not then click on my created elements to trigger the click listener. I tried putting the addEventListener in other places, but it seems to keep being associated with my search button element instead of the “more details” divs I am creating.

let dayDivDetails = document.getElementById(`dayDivDetails${i+1}`)
dayDivDetails.addEventListener("click", console.log("hi"))

Here is the full loop:

      //fill the divs with weather info
      for(let i=0; i<5; i++){
        //days and dates
        document.getElementById(`dayDivDate${i+1}`).innerHTML = parseApiInfo(weatherData).dates[i]
        document.getElementById(`dayDivDay${i+1}`).innerHTML = parseApiInfo(weatherData).weekdays[i]
        document.getElementById(`dayDivDesc${i+1}`).innerHTML = parseApiInfo(weatherData).descriptions[i]
        document.getElementById(`dayDivImg${i+1}`).src = `http://openweathermap.org/img/w/${parseApiInfo(weatherData).icons[i]}.png`
        let dayDivDetails = document.getElementById(`dayDivDetails${i+1}`)
        dayDivDetails.innerHTML = "See Hourly"
        dayDivDetails.className += "dayDivDetails"
        //make it so you can click on a day for more info
        dayDivDetails.addEventListener("click", console.log("hi"))
        // createHourDivs(weatherData, parseApiInfo(weatherData).datesOriginal[i])
        //high and low temps
        let fTempMin = Math.round(1.8*(tempMinMax(weatherData).minTemps[i]-273) + 32)
        let fTempMax = Math.round(1.8*(tempMinMax(weatherData).maxTemps[i]-273) + 32)
        document.getElementById(`dayDivTemp${i+1}`).innerHTML = `${fTempMax}° F / ${fTempMin}° F`
      }

The full repo:


#2

Which file contains the code above?


#3

Hi Randell,

It is in weather.js


#4

Here is what I see in weather.js. I only see a single click event handler and it is not inside a for loop.

// 'http://api.openweathermap.org/data/2.5/forecast?q=London,uk&APPID=55bd4eb052cb7c72fd8594fbd1ee7fee'

let urlRoot = 'http://api.openweathermap.org/data/2.5/weather?q='
let apiID = '55bd4eb052cb7c72fd8594fbd1ee7fee'

let button = document.getElementById('submit')
let cityInput = document.getElementById('cityInput')
let countryInput = document.getElementById('countryInput')

button.addEventListener('click', function(){
  getWeather(cityInput.value, countryInput.value)
})

function getWeather(city,country){

  let fullUrl = `http://api.openweathermap.org/data/2.5/forecast?q=${city},${country}&APPID=${apiID}`
  if(!country) fullUrl = `http://api.openweathermap.org/data/2.5/forecast?q=${city}&APPID=${apiID}`
  if(!city) fiveDayTitle.innerHTML = 'Please enter a city'

  let xhr = new XMLHttpRequest()
  xhr.open('GET', fullUrl, true)
  xhr.onload = function(){
    if(this.status === 200){
      let weatherData = JSON.parse(this.responseText)
      console.log(weatherData);

      fiveDayTitle.innerHTML = weatherData.city.name + " " + weatherData.city.country

      //fill the divs with weather info
      for(let i=0; i<5; i++){
        //days and dates
        document.getElementById(`dayDivDate${i+1}`).innerHTML = weekdaysAndDates(weatherData).dates[i]
        document.getElementById(`dayDivDay${i+1}`).innerHTML = weekdaysAndDates(weatherData).weekdays[i]
        document.getElementById(`dayDivDesc${i+1}`).innerHTML = weekdaysAndDates(weatherData).descriptions[i]
        document.getElementById(`dayDivImg${i+1}`).src = `http://openweathermap.org/img/w/${weekdaysAndDates(weatherData).icons[i]}.png`
        //high and low temps
        let fTempMin = Math.round(1.8*(tempMinMax(weatherData).minTemps[i]-273) + 32)
        let fTempMax = Math.round(1.8*(tempMinMax(weatherData).maxTemps[i]-273) + 32)
        document.getElementById(`dayDivTemp${i+1}`).innerHTML = `${fTempMax}° F / ${fTempMin}° F`
      }

    } else {
      console.log('error: xhr not 200');
    }
  }
  xhr.send()
}


#5

My mistake, I thought I had the most recent version on github. I just pushed a new commit with the most recent code.


#6

You have a statement instead of a function. Wrap console.log(“hi”) inside a an anonymous function, so the console.log is only executed when the click event occurs.


#7

Thank you Randell,

You have saved me from much anxiety. Your help is very appreciated.