1

Pulling my hair out here.

Jquery, Multiple JSON files & Ajax

I have a python script that is gathering data and dumping JSON files into a folder on my webserver

I am trying to visualise that data.

Basically I am first drawing an SVG map and coloring it in with a dummy json file. Subsequently I want to color it in using the JSON data. Each JSON file will represent one complete rendering (coloring) of the map.

I am using an Ajax call to a php script that returns the files in the directory. I then want to use Ajax (or the shorthand .getJson) to lad the data in that file -colour the map, and then move on to the next one (end result is an animation). The problem is the asynchronous nature of AJAX and not having any control over the timely execution and completion of the Ajax bit. Obviously i don't want to make a synchronous call because i don't want to lock up the browser.

Here's my code (apologies -it's fairly hefty)

jQuery(document).ready(function() {

$(function() {

    var map, c = [];
    var dep_data;
    var val = {};
    var max= 0;
    var vals = new Array();

    c = $('#map');
    c.height(c.width()*.5);

    drawMap('mapData.json');

    function drawMap(url){
        console.log(url);
        $.ajax({
        url: 'mapData.json',
        dataType: 'json',
        success: function(data) {

            dep_data = data;

            map = window.m = $K.map('#map', 600, 800);
            map.loadMap('ireland.svg', function() {
                map.loadStyles('./mapping_files/style.css');
                map.addLayer({
                    id: 'regions',
                    key: 'name-1'
                });

                colourMap(dep_data);

                    var mapData = $.ajax({
                        url: './php/getfiles.php',
                        type : 'POST',
                        dataType: 'json',
                        success: function (files){

                            for (_a in files.response){
                                for (_b in files.response[_a]){
                                      $.ajax({
                                        url: files.response[_a][_b],
                                        dataType: 'json',
                                        success: function (json){
                                          colourMap(json);
                                          $(this).dequeue();
                                        }
                                      });
                                }       

                            }
                        },

                        error: function (files){
                            console.log(files.message);
                        },

                    });

                });

            }
        });



    }

    colourMap = function(data) {

    //do the coloring in...

}

}); });
2
  • why the downvote? not a terrible question. title could be clearer but doesn't warrant downvoting a new user imo. Commented Apr 13, 2012 at 14:18
  • thank's jammy peach :) It seems what i want is sequential AND asynchronous... Commented Apr 13, 2012 at 14:44

2 Answers 2

0

Ok,

You might want to decouple your json processing code from the ajax success() function. Instead, sort the data and store it in a global variable. Once all data has been received (check for that), you can call a function to draw your SVG, thus having control over timing. Its like the $.document(ready) of jquery

EDIT:

Depending on your scenario, you need a more efficient queue system for your json files. One method would be to load json files in chunks instead of randomly. You've mentioned that a new file is created every 10 minutes, so obtain the first json file and acquire, lets say, 35 more json files, in effect obtaining 6 hours of data. If one folder currently has less than 36 files, you can choose to wait until all 36 are present, then run the svg code and move on to, or wait for, the next 36 json files. This brings in control over timing, where one svg file represents 6hrs of data. You can also change from 36 to any reasonable value

Sign up to request clarification or add additional context in comments.

10 Comments

That's kinda where i was headed but once I call the AJAX function to get the JSON filenames in the directory how can i be sure i've got them all (and the order is important) before i start executing my next set of AJAX functions -again, i want these done sequentially but also asynchronously because they are time stamped and the order they are rendered in is important...
ok ask yourself, do new json files come in while you are drawing the svg (calling getfiles.php)?
how do you choose which json files to obtain in getfiles.php? be specific please
Preferably all of them, a new folder is created every day and a json file is created and dumped into that folder every 10 minutes. So the number of files returned will vary depending on the time of day. Early on it will be just a few, by later that day it could be 100+ files. Or i could load 144 at a time so it's a rolling 24hr thing... or fewer... depending on performance.
` $date = date("dmY"); //path to directory to scan $directory = "../json_data/" . $date . "/"; //get all files with a .json extension. $files = glob($directory . "*.json"); foreach ($files as &$file){ $file = substr($file, 1); } $json = json_encode($files); if ($files){ // To return a successful response echo json_encode( array( 'success' => true, 'response' => array($files), ) ); } else { // To return an error echo json_encode( array( 'error' => true, 'message' => 'Error', ) ); }`
|
0

Found an awesome solution here that i have tweaked a little as below. Works perfectly. Thanks for the input on this one guys.

        function getFiles(){

        $.ajax({
            url: './php/getfiles.php',
            type : 'POST',
            dataType: 'json',
            success: function (files){

                for (_a in files.response){
                    for (_b in files.response[_a]){
                        var fname = files.response[_a][_b].substr(30, 8);
                        jsonVals[fname] = files.response[_a][_b];
                    }       
                }

                getData();

            },

            error: function (files){
                console.log(files.message);
            },

        });

    }


    function getData(){

        _d = 0;

        function fireRequest(jsonURL) {
                return $.ajax({
                    type: "GET",
                    url: jsonURL,
                    dataType: 'json',
                    success: function(data){
                        console.log("got " + jsonURL);
                        if (_d == Object.size(jsonVals)){ console.log('done'); }


                    }
                });
        }

        var countries=["US","CA","MX"], startingpoint=$.Deferred();
        startingpoint.resolve();

        $.each(jsonVals,function(key, file) {
            startingpoint=startingpoint.pipe( function() {
                    console.log("making requst for " + file);
                    _d = _d + 1;
                    return fireRequest(file);
            });
        });


    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.