Radu Dascălu Radu Dascălu - 6 months ago 39
Javascript Question

addEventListener not working as intended inside for loop

I am trying to make a calendar/schedule in JS, and the method

used on a scheduled event returns the same event id, when it should return the id of the clicked event.

This is the function I have at the moment:

monthStart = date.clone().subtract(1, 'months').endOf 'month'
monthEnd = parseInt date.clone().endOf('month').format 'DD'
daysContainer = @createElement 'div', 'calendar__days'

for i in [1..monthEnd]
day = monthStart.add 1, 'day'
current = day.format 'DD-MM-YYYY'

line = @createElement 'div', 'calendar__line'
line.classList.add 'line--today' if current == @current.format 'DD-MM-YYYY'

header = @createElement 'div', 'line__header'
header.appendChild @createElement 'h1', 'line__date', day.format 'DD'
header.appendChild @createElement 'span', 'line__day', day.format 'dd'
events = @createElement 'div', 'line__events'

events_data = @parseEventsPerDay current
for event in events_data
event_block = @createElement 'div', 'event'
x = event.id
event_block.addEventListener 'click', => console.log event.id <<---------- this line returns always the same id
event_container = @createElement 'div', 'event__container'
event_block.appendChild @createElement 'div', 'event__bbg' + ' ' + @resolveColor 'bg', event.type
event_container.appendChild @createElement 'div', 'event__timeinterval', event.timeStart + ' - ' + event.timeEnd
event_container.appendChild @createElement 'div', 'event__content' + ' ' + @resolveColor('link', event.type), event.title

event_block.appendChild event_container
events.appendChild event_block

line.appendChild events
line.appendChild header
line.appendChild events
daysContainer.appendChild line

@el.appendChild daysContainer

Also any ideas, tips, tutorials for the entire project, for my code, are welcome.


As @robiseb mentioned in a comment, you need to use closures to ensure that the current event is a local variable inside the closure of the loop, rather than a global variable.

For details on closures, see this question.

Coffeescript supplies us with the do keyword to make this easier. See the last example in the loops and comprehensions coffee docs.

for event in events_data
  do(event) ->
    event_block = @createElement 'div', 'event'
    x = event.id
    event_block.addEventListener 'click',  => console.log event.id