Passing array and index within `for` loop and `setTimeout()` [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I would like to execute a click on templates[i] within setTimeout within a for loop
for(var i=0; i<templates.length; i++){
setTimeout(function(){
(function(){
templates[i].click();
}(i, templates));
}, 200);
}
I get the error templates[i] is undefined.
However, something like this works fine:
for(var i=0; i<templates.length; i++){
setTimeout(function(){
(function(){
console.log(templates_arr+templates)
}(templates_arr, templates));
}, 200);
}
Can anybody shed some light onto why this is like this and how I can pass the array and index properly?
Thanks,
Dan

it should be
for(var i=0; i<templates.length; i++){
(function(i,templates){
setTimeout(function(){
templates[i].click();
}, 200);
})(i, templates);
}

Related

Why it says push is not a function when called? [duplicate]

This question already has an answer here:
Why does [].push([]) return 1? [duplicate]
(1 answer)
Closed 3 years ago.
function rotLeft(a, d) {
var temp=[];
temp=a.splice(0);
for(let i=0; i<d-1; i++)
{
var first=temp.shift();
temp=temp.push(first);
}
var result=temp;
return temp;
}
if you know the rotate left problem in hackerrank, why woudnt this code work. The console says push is not a function. whats wrong in this code. Also please explain arr.shift(arr.push(arr[0])); this line. The first element is pushed to the last element and the first element is removed?
It should be temp.push(first); not temp=temp.push(first);
function rotLeft(a, d) {
var temp=[];
temp=a.splice(0);
for(let i=0; i<d-1; i++)
{
var first=temp.shift();
temp.push(first);
}
var result=temp;
return temp;
}
console.log(rotLeft([1,2,3,4,5,6],8))

Define function based on global variable in javascript [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I'm trying to print out a number every 5 seconds:
for(i=0; i<10; i++) {
setTimeout(function() {
console.log(i)
}, 5000 * i);
}
But instead I print 10 every 5 seconds because the loop finished and the global variable i is ten. Is there a way to avoid this happening?
You can use bind to create a closure:
for (i = 0; i < 10; i++) {
setTimeout((function(num) {
console.log(num);
}).bind(this, i), 5000 * i);
}
If ES6 Is allowed you could use a let declaration.
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i)
}, 5000 * i);
}
The setTimeout function in javascript doesn't work like time.sleep(n) in python. The code will not pause and continue to run after 5s. It will set the body of the function in a queue that will be served in the time you picked. Since you loop 10 times, it will set all of your orders which are basically print i in a queue and serve them all together. To avoid this you can make a use of your loop in something that looks quite like this
setTimeout(function(){ console.log(i)}, 5000*i);
which will schedule each if the print 5s away from the last one !

Passing a variable to a click function created in for loop [duplicate]

This question already has answers here:
Javascript multiple dynamic addEventListener created in for loop - passing parameters not working
(5 answers)
Closed 7 years ago.
Basically I created a bunch of cells and I am trying to add onclick to each one passing a variable to use inside the function. But doing straight up passes the 'i' variable as the last i value and not 0,1,2,3,4 etc. Here is a snippet of what I am doing.
for (var i = 0; i < cellCount.length; i++) {
var cellName= "cell"+ i
document.getElementById(cellName).onclick = function () { cellClicked(i) };
}
If you do not "capture" the value in a new scope, the callback will read the value from the actual i-counter.
Do something like this:
for (var i = 0; i < cellCount.length; i++) {
(function(copy_of_i) {
var cellName= "cell"+ i
document.getElementById(cellName).onclick = function () { cellClicked(copy_of_i) };
})(i)
}

Save value of variable within callback [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I have the following code:
<div id="0">click here</div>
<div id="1">click here</div>
<div id="2">click here</div>
for(var i=0;i<3;i++){
document.getElementById(i).addEventListener("click",function(){
alert(i);
});
}
How can I get my callback function to alert 1, then 2 and then 3? It always alerts 3, and I need a way for it to save the value of 'i' at each iteration.
for(var i=0;i<3;i++) {
document.getElementById(i).addEventListener("click", (function() {
var j = i;
return function() {
alert(j);
}
})();
);
}
Also this one should work:
for(var i=0;i<3;i++) {
document.getElementById(i).addEventListener("click", (function(j) { alert(j); }).bind(undefined,i));
}
A global counter variable can be used to count the number of clicks.
var counter = 1;
for(var i=0;i<3;i++){
document.getElementById(i).addEventListener("click",function(){
alert(counter++);
});
}

Why 'i' passed to a function inside a for loop is equal to a number greater than 'i'? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I have this for loop:
for (var i = 1; i < array.length; i++) {
$('#shop'+i).on('click', function(){ buyThis(i) });
}
The problem is that the i passed as argument to buyThis() isn't equal to the i.
array.length is equal to 3 and #shop1 and #shop2 are created but the argument passed to buyThis() is 3. Why is that?
I'm trying to get an event in which clicking on #shop1 triggers buyThis(1) and clicking on #shop2 triggers buyThis(2).
That's because the code inside the function is called later, when the loop has finished and the variable i has reached its final value.
You can wrap the code that sets the event in an immediately invoked function expression (IIFE) to create a variable for each iteration of the loop:
for (var i = 1; i < array.length; i++) {
(function(i){
$('#shop' + i).on('click', function(){ buyThis(i); });
})(i);
}
This is a scope issue. You need to create a proper closure
for (var i = 1; i < array.length; i++) {
(function(index){
$('#shop'+index).on('click', function(){ buyThis(index) });
})(i);
}
The reason it was different before is because in javascript. the variable is still visible to the handler and by the time it is accessed, it is set to the latest iteration.
This is an issue with block scoping, you can use a closure to solve this
for (var i = 1; i < array.length; i++) {
(function(index){
$('#shop'+index).on('click', function(){ buyThis(index) });
})(i);
}

Categories

Resources