Frankie Dee
Frankie Dee

Reputation: 61

Passing array values as function parameter

Hi I am trying to write code for an image to change every second depending on what is stored in an array. Heres what I have so far:

function parse_input(){
    //initializes the input_text and the text_array variables
    var input_text=document.getElementById('input_text').value;
    var text_array=[];
    //loops through input_text and if it is an alphanumeric character...pushes it to the text_array
    for(var letter in input_text){
        const LETTER_REGEX=/^[a-zA-Z0-9]+$/;

        if(LETTER_REGEX.test(input_text[letter])){
            text_array.push(input_text[letter]);
        }
    }
    //function to change the image
    function change_image(array){
            document.getElementById('letter_image').src="images/"+array+".png";
            document.getElementById('letter_image').alt=array;
    }
    //supposed to loop through the text_array and change the image every second.
    for(var i=0;i<text_array.length;i++){
        setTimeout(function(){change_image(text_array[i])},1000*i);
    }
}


window.onload=function(){
    document.getElementById('finger_spell_it').onclick=function(){
        parse_input();
    }
}

When I go to run the test I get an undefined variable. I don't know what I am doing wrong please help.

Upvotes: 0

Views: 86

Answers (2)

R. Oosterholt
R. Oosterholt

Reputation: 8080

You need closure. This is elaborately explained here:

That is a closure. A function doesn't have to return in order to be called a closure. Simply accessing variables outside of your immediate lexical scope creates a closure.

function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + (++tmp));
  }
}
var bar = foo(2); // bar is now a closure.
bar(10);

The above function will also alert 16, because bar can still refer to x and tmp, even though it is no longer directly inside the scope.

for your code example:

for(var i=0;i<text_array.length;i++){
    (function(index){
        setTimeout(function(){
            change_image(text_array[index])
        }, 1000 * index);
    })(i);
}

closure can also be created using thirdparty tollboxes like jQuery proxy:

for(var i=0;i<text_array.length;i++){
    setTimeout($.proxy(function(index){
            change_image(text_array[index])
        }, this, i)
    , 1000*i);
}

or using underscore.js bind

for(var i=0;i<text_array.length;i++){
    setTimeout(_.bind(function(index){
            change_image(text_array[index])
        }, this, i)
    , 1000*i);
}

Upvotes: 0

qwertynl
qwertynl

Reputation: 3933

When your setTimeout runs, i is already at an undefined index.

You need to create a scope for it:

// ...

for(var i=0;i<text_array.length;i++){
    (function(index){
        setTimeout(function(){
            change_image(text_array[index])
        }, 1000 * index);
    })(i);
}

// ...

Upvotes: 3

Related Questions