diegoaguilar
diegoaguilar

Reputation: 8376

Issue with setTimeout function's variables inside a function executed as callback

I'm trying to execute some statements with setTimeout, inside the function plotReglaFalsa which is actually executed as callback at getSendingJSON("/plot",args,plotReglaFalsa)

This is is code snippet where sentences are executed by setTimeout:

for (series in respuesta) {
                if (series != "x" && series != "y" && series != "raiz") {

                    setTimeout(function(respuesta,series){plot.highlight(c,[respuesta[series].a,0])},1500)                      
                    setTimeout(function(respuesta,series){plot.highlight(c,[respuesta[series].b,0])},1800)  
                    c++
                }
}

The issue here is that respuesta and so series are actually existing once the callback happens.

When I try to run I get the following console outputs:

TypeError: series is undefined


...Timeout(function(respuesta,series){plot.highlight(c,[respuesta[series].a,0])},15...

16
biseccion.js (line 50)
TypeError: series is undefined


...Timeout(function(respuesta,series){plot.highlight(c,[respuesta[series].b,0])},18...

This is my whole code:

function plotReglaFalsa(respuesta) {

            var result = []

            result.push({
            label: "fx",
            color: "red",
            data: _.zip(respuesta['x'], respuesta['y'])
            })

            for (series in respuesta) {
                if (series != "x" && series != "y" && series != "raiz") {
                    result.push({
                        color: "blue",
                        data: [[]]
                    })
                }
            }

            var plot = $.plot(  $("#placeholder"), 
                                result, 
                                {   selection:{mode: "xy"},  
                                    zoom: { interactive: true }, 
                                    pan: { interactive: true }, 
                                    grid: { markings: [{ xaxis: { from: 0.0, to: 0.0 }, color: 'black', lineWidth: 2 }, { yaxis: { from: 0.0, to: 0.0 }, color: 'black', lineWidth: 2 }] }
                                })
            plot.getOptions().selection.mode = null

            var c = 1

            for (series in respuesta) {
                if (series != "x" && series != "y" && series != "raiz") {

                    setTimeout(function(respuesta,series){plot.highlight(c,[respuesta[series].a,0])},1500)
                    setTimeout(function(respuesta,series){plot.highlight(c,[respuesta[series].b,0])},1800)
                    c++
                }
            }

        }

        getSendingJSON("/plot",args,plotReglaFalsa)


            function resaltarPuntos(plot,respuesta,series,c,x){
            plot.highlight(c,[respuesta[series].x,0])
        }

        function desResaltarPuntos(plot){
            plot.unhighlight()
        }

getSendingJSON is actually AJAX. How can I get this completed?

Upvotes: 0

Views: 254

Answers (1)

market
market

Reputation: 473

as per elclanrs' comment:

every time the code iterates through the for loop it modifies the value of series. so by the time your setTimeout() is called, the value of series has been updated to the last value in respuesta.

You need to utilize a closure so your setTimeout() uses the value of series as it was during that iteration.

for (series in respuesta) {
    if (series != "x" && series != "y" && series != "raiz") {
        (function(x){
            setTimeout(function(){plot.highlight(c,[respuesta[x].a,0])},1500);                     
            setTimeout(function(){plot.highlight(c,[respuesta[x].b,0])},1800);
            c++;
         }(series))
    }     
}

Upvotes: 1

Related Questions