0

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?

diegoaguilar
  • 8,179
  • 14
  • 80
  • 129

1 Answers1

1

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))
    }     
}
market
  • 473
  • 1
  • 4
  • 9
  • This will only work if you remove the parameters from the anonymous functions passed to `setTimeout()`. – cookie monster Feb 25 '14 at 03:35
  • 1
    Actually, the intent is to **avoid** the consequences of closures by assigning the value to a different variable that is not updated by the loop. – RobG Feb 25 '14 at 03:40
  • Is that why anonymous function receives *`x`*? – diegoaguilar Feb 25 '14 at 03:41
  • 1
    @diegoaguilar—yes. The value of *series* in the loop is passed to *x*, which is then available to the function passed to *setTimeout*. A new instance of *x* is created on each loop for each function, avoiding the consequences of multiple references to the one instance of *series*. – RobG Feb 25 '14 at 03:44
  • I tried the last edit to this answer and YET I get series as undefined ... I tried even adding respuesta and series as last parameters to `setTimeout` – diegoaguilar Feb 25 '14 at 03:46
  • 1
    @diegoaguilar: The `respuesta,x` parameters need to be removed from the functions being passed in order for this technique to work. `setTimeout(function(){...` – cookie monster Feb 25 '14 at 03:47
  • I think my issue now is more about the c variable. I'm using flot library and the error I'm getting is about the library: `TypeError: hi.series is undefined if (hi.series.bars.show)` – diegoaguilar Feb 25 '14 at 03:53
  • Removed the arguments from the functions being passed to setTimeout(), as per cookie monster's comments. Hadn't noticed that before. – market Feb 25 '14 at 04:08