1

I was using the "this" keyword here in my code and decided to replace that with squares[i]. As I click the div, my console is showing me error message: "Cannot read propery of undefined".

var colors=[
"rgb(255, 0, 0)",
"rgb(255, 255, 0)",
"rgb(0, 255, 0)" ,
"rgb(0, 255, 255)",
"rgb(0, 0, 255)",
"rgb(255, 0, 255)" ];

var squares=document.querySelectorAll(".square");
var pickedColor=colors[3];
var display=document.getElementById("colorDisplay");
display.textContent=pickedColor;

for(var i=0;i<squares.length;i++){
//ADD INITIAL COLORS TO SQUARES
squares[i].style.backgroundColor=colors[i];
//ADD EVENTLISTENERS TO SQUARES
squares[i].addEventListener("click",function(){
    console.log(squares[i].style.backgroundColor);
 });
}

//__________________________________________________________________________
//This is the correct version of the code
 var colors=[
"rgb(255, 0, 0)",
"rgb(255, 255, 0)",
"rgb(0, 255, 0)" ,
"rgb(0, 255, 255)",
"rgb(0, 0, 255)",
"rgb(255, 0, 255)" ];

var squares=document.querySelectorAll(".square");
var pickedColor=colors[3];
var display=document.getElementById("colorDisplay");
display.textContent=pickedColor;

for(var i=0;i<squares.length;i++){

//ADD INITIAL COLORS TO SQUARES
squares[i].style.backgroundColor=colors[i];
//ADD EVENTLISTENERS TO SQUARES
squares[i].addEventListener("click",function(){
    console.log(this.style.backgroundColor);
 });
}

I have added two versions of the code. The first one is incorrect, while the second one is the correct one.

Encrypted Drink
  • 91
  • 1
  • 11
  • What is the value of `squares.length`? – Prerak Sola Feb 15 '19 at 16:17
  • Show us before and after. The provided code snippet does not give clear context – yqlim Feb 15 '19 at 16:17
  • 2
    You nead to learn about [Javascript Closure](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work). The `i` in your event listener function will always be set to `squares.length`, which is outside of the index – freefaller Feb 15 '19 at 16:17
  • squares[i].length= 6 – Encrypted Drink Feb 15 '19 at 16:18
  • 1
    `i === squares.length` when your loop completes, which is before any click handlers are called, so inside your click handler you're accessing `squares[squares.length]` which is undefined. – Paul Feb 15 '19 at 16:18
  • Perhaps i is out of scope in the event listener function? –  Feb 15 '19 at 16:18
  • Still dont get it :( – Encrypted Drink Feb 15 '19 at 16:42
  • 1
    @Usama Add `console.log( i, squares[i] );` after your loop, and consider that the log runs before you every click on anything. Then when you click on something, it's no different. Put `console.log( i, squares[i] );` inside your click event listener too. – Paul Feb 17 '19 at 00:04
  • @Usama After doing that you will understand the problem, then read the linked duplicate to learn about various solutions. My favourite that works in modern browsers but not some very old browsers, is to just change `var i=0` to `let i=0`. – Paul Feb 17 '19 at 00:04

0 Answers0