0

jQuery to update values with done, fail

The Javascript, jQuery asynchronous and scope things are driving me crazy.

Output is:

3rd: 5 5 5 5 
1st 1: 5 5 5 5
1st 2: 9 36 284 340
2nd 9 36 284 340 
1st 1: 9 36 284 340
1st 2: 10 37 284 340
2nd 10 37 284 340 
...

All I want is to make the output to be:

1st 2: 10 37 284 340
2nd 10 37 284 340 
3rd: 10 37 284 340
...

so that I can pass the updated values:

Code is as follows:

series: [{
    data: (
        function() {

            y1 = 5,
            y2 = 5,
            y3 = 5,
            y4 = 5;

            function myFunction() {
                return $.ajax({
                    type: "GET",
                    url: "/getTest",
                    success: function(data) {
                        console.log("1st 1:", y1, y2, y3, y4);
                        y1 = data.V1;
                        y2 = data.V2;
                        y3 = data.V3;
                        y4 = data.V4;
                        console.log("1st 2:", y1, y2, y3, y4);
                    }
                });
            };

            var data = [],
                time = (new Date()).getTime(),
                i;
            for (i = -60; i <= 0; i++) {
                myFunction().done(function() {
                    console.log("2nd", y1, y2, y3, y4);
                }).fail(function() {
                    console.log("Fail");
                });
                console.log("3rd:", y1, y2, y3, y4);
                data.push({
                    x: time + i * 30,
                    y: 0
                });
            }
            return data;
        }()
    )
}],

The problem is console.log("3rd:"~), runs first so it is not being updated. What should I do to return the values from GET in HighChart.

1 Answers1

0

Your anonymous function is returning the array before any of your AJAX calls return. You need to set up your chart, then make your data calls and set the value of your series when they return. Something like:

var chart = $('#container').highcharts({
    series: [{
        data: (

        function () {

            //We'll initialize an array of zeroes to set your series up
            var initialData = [];
                //This will eventually be populated with our data
            var ajaxData = [];
            //References to all our requests we'll make
            var ajaxRequests = [];

            y1 = 5,
            y2 = 5,
            y3 = 5,
            y4 = 5;

            function myFunction(x) {
                return $.ajax({
                    type: "GET",
                    url: "/getTest",
                    success: function (data) {
                        console.log("1st 1:", y1, y2, y3, y4);
                        y1 = data.V1;
                        y2 = data.V2;
                        y3 = data.V3;
                        y4 = data.V4;
                        console.log("1st 2:", y1, y2, y3, y4);
                        //Add the returned data to our array in the correct position
                        ajaxData.push({
                            x: x,
                            y: y1
                        });
                    }
                });
            };

            var time = (new Date()).getTime(),
                i;

            for (i = -60; i <= 0; i++) {
                //Push this initial node
                var x = time + i * 30;
                initialData.push({
                    x: x,
                    y: 0
                });
                //Fire off our ajax request, passing in the x value
                ajaxRequests.push(myFunction(x));
            }

            //Create a "master" request that will only be complete when all the ajax is done
            //When all requests are done, load the data into the chart
            //"apply" passes our array as arguments, i.e. function.apply($, [1, 2, 3]) === $.function(1,2,3)
            $.when.apply($, ajaxRequests).then(function() {
                console.log('Done getting ' + ajaxData.length + ' points');
                //Update the data of the first series in the chart
                chart.series[0].setData(ajaxData);
            });

            //Remember, this is dummy data...
            return initialData;
        }())
    }] //...
});

http://jsfiddle.net/2s2bf69c/3/

3bh
  • 806
  • 1
  • 6
  • 12
  • I still need to push the data in `initialData.push({` but inside `initialData.push({` I cannot access to `y1`, `y2`, ... –  Aug 22 '14 at 06:45
  • You can't have them in initialData unless you want to wait until all your remote calls come back before the call to highcharts() - the data simply isn't available, which is why you have to wait until they're all done and then call series.setData(). – 3bh Aug 22 '14 at 14:08