Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught ReferenceError: i is not defined

Tags:

I'm trying to make a for-loop base on my array

var lists = [ "a", "b", "c", "d" ];


JS

for ( i = 0; i < lists.length; i++) {      // console.log(lists[i]);      $(".sa-report-btn-"+lists[i] ).click(function () {         $(".sa-hide-"+lists[i]).removeClass("hidden");         $(".sa-report-"+lists[i]).addClass("hidden");     });      $(".sa-hide-btn-"+lists[i]).click(function () {         $(".sa-hide-"+lists[i]).addClass("hidden");         $(".sa-report-"+lists[i]).removeClass("hidden");     }); } 

Am I doing it correctly ? I got Uncaught ReferenceError: i is not defined Can I concat each loop with my jQuery selector like this --> $(".sa-hide-"+lists[i]) ? just curious ...

like image 225
code-8 Avatar asked Jun 29 '15 16:06

code-8


People also ask

How do I fix uncaught ReferenceError is not defined?

Answer: Execute Code after jQuery Library has Loaded The most common reason behind the error "Uncaught ReferenceError: $ is not defined" is executing the jQuery code before the jQuery library file has loaded. Therefore make sure that you're executing the jQuery code only after jQuery library file has finished loading.

What does uncaught ReferenceError mean?

The Javascript ReferenceError occurs when referencing a variable that does not exist or has not yet been initialized in the current scope.

Is not defined error in HTML?

Basically $ is an alias of jQuery() so when you try to call/access it before declaring the function, it will endup throwing this $ is not defined error . This usually indicates that jQuery is not loaded and JavaScript does not recognize the $. Even with $(document).

Is not defined in angular?

While programming in JavaScript, jQuery or Angular JS, coders often encounter an error called Uncaught ReferenceError: $ is not defined. This usually happens when the $, that may be a variable or a method is not properly defined but is being used.


1 Answers

First off, it sounds like you're using strict mode — good! It's saved you from falling prey to The Horror of Implicit Globals.

There are two issues with the code.

The first one is that you're missing the declaration for i. You need to add var i; above the loop, e.g:

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

or

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

Note, though, that even in that latter example, the i variable is function-wide, not limited to the for loop.

The second one is more subtle, and is outlined in this question and its answers: Your click handlers will have an enduring reference to the i variable, not a copy of it as of where they were created. So when they run in response to a click, they'll see i as the value lists.length (the value it has when the loop has finished).

In your case, it's really easy to fix (and you don't have to declare i anymore): Remove the loop entirely, and replace it with Array#forEach or jQuery.each:

lists.forEach(function(list) {      $(".sa-report-btn-" + list).click(function () {         $(".sa-hide-" + list).removeClass("hidden");         $(".sa-report-" + list).addClass("hidden");     });      $(".sa-hide-btn-" + list).click(function () {         $(".sa-hide-" + list).addClass("hidden");         $(".sa-report-" + list).removeClass("hidden");     }); }); 

If you need to support really old browsers, you can either shim Array#forEach (which was added in 2009, as part of ECMAScript5), or you can use $.each (jQuery.each) instead:

$.each(lists, function(index, list) { // Note addition ------^     $(".sa-report-btn-" + list).click(function () {         $(".sa-hide-" + list).removeClass("hidden");         $(".sa-report-" + list).addClass("hidden");     });      $(".sa-hide-btn-" + list).click(function () {         $(".sa-hide-" + list).addClass("hidden");         $(".sa-report-" + list).removeClass("hidden");     }); }); 

Note that we don't actually use index anywhere in our callback, but we have to specify it because $.each calls our callback with the index as the first argument, and the value as the second. (Which is why I prefer Array#forEach.) So we have to accept two arguments, with the one we want being the second one.

like image 177
T.J. Crowder Avatar answered Sep 19 '22 13:09

T.J. Crowder