javascript/jQuery getJSON very slow with a inner loop - javascript

I'm using OpenLayers to render DOM for layerswitcher, with about 1200 divs. The problem can be simplified as follows.
This is very fast (3 seconds or so):
var allLayers = [layerMapnik, layerCycleMap];
for(var ii = 0; ii < 1200; ++ii) {
console.log("ii = " + ii.toString());
var groupName = "wms/Transit/railroad/image/" + ii;
var layName = "CycleMap" + ii.toString();
var oneLayer = new OpenLayers.Layer.XYZ(layName, "http://whatever/tile/${z}/${y}/${x}", {visibility: false, group:groupName});
allLayers.push(oneLayer);
}
console.log("adding layers");
map.addLayers(allLayers);
$.getJSON("sampleArray.json", {}, function( doc ) {
console.log(doc.length);
});
But once the for-loop is put inside the getJson callback, it's painfully slow and freezes the browser, even when the for-loop is not reading the 'doc' at all!
var allLayers = [layerMapnik, layerCycleMap];
$.getJSON("sampleArray.json", {}, function( doc ) {
console.log(doc.length);
for(var ii = 0; ii < 1200; ++ii) {
console.log("ii = " + ii.toString());
var groupName = "wms/Transit/railroad/image/" + ii;
var layName = "CycleMap" + ii.toString();
var oneLayer = new OpenLayers.Layer.XYZ(layName, "http://whatever/tile/${z}/${y}/${x}", {visibility: false, group:groupName});
allLayers.push(oneLayer);
}
console.log("adding layers");
map.addLayers(allLayers);
});
No matter how simple the json file is sampleArray.json:
[
{
"a": 123,
"b": 456
},
{
"c": "ccc",
"d": "ddd"
}
]
Did I use the getJSON or callback wrong? Or it is an OpenLayer thing?
I also tried $.each instead of for-loop, no help.

Answering my own questions, for future reference.
The adding LayerSwitcher should be inside the callback function too. Because the whole LayerSwitcher div should be generated BEFORE adding it to the main html, otherwise the redraw for every added layer in the switcher slows things down and freezes the browser.
Also, it is helpful to have the $.ajax call outside the $(document).ready(), to speed things up, since the data fetching does not need to wait for the $(document)

Related

Google Visualizations: Where does JS execution begin again after drawing charts?

A small project using Google Visualizations, https://jsfiddle.net/brisray/qsgewt2d/ - works as far as I have it, but I have a question about it.
Once the graphs are drawn, I assumed that control would pass back to "mainFunction". This is a function that loops through the object array I made creating the queries, then calls other functions that draws the tables and charts. I was hoping to add more code to that function to call other functions for other things I want to do.
What I find is that it doesn't work that way. A simple JS alert AFTER the loop shows none of the drawing is done until the alert is acknowledged.
Am I missing something? Perhaps an event handler that's triggered after the last of the array is processed and the last of the initial graphs drawn? Something to do with the asynchronous natures of the drawing.
Is there something fundamentally wrong with the code and the way I've written it?
Whatever is happening, I cannot see it, so would appreciate some help.
Ray
var SCOB_metrics = (function() {
// Create the object array that is global to the namespace
var graphArray = [];
// Create objects and push them to the array
// Object properties are: ID, sheet, GID, datatable, graphtype, rotated
createObject('MSDC', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '1835225366', 'MSDC_data', 'Column', false);
createObject('StudentPop', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '3256521', 'StudentPop_data', 'Column', false);
createObject('EnrolTrends', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '1037635451', 'EnrolTrends_data', 'Column', false);
google.charts.load('current');
google.charts.setOnLoadCallback(mainFunction);
function mainFunction() {
for (i = 0; i < graphArray.length; i++) {
makeQuery(graphArray[i]);
}
// Now everthing is drawn, set up the listener for the drawingArea div
// so that the graphs can be updated if needed
var theParent = document.querySelector("#drawingArea");
theParent.addEventListener("change", whichDrop, false);
}
function makeQuery(myObject) {
// Create the querystring and send it
var queryStr = "https://docs.google.com/spreadsheets/d/" + myObject.sheet + "/gviz/tq?gid=" + myObject.GID + "&headers=1";
var query = new google.visualization.Query(queryStr);
/* You can't send a variable though the normal query.send method
query.send(handleQueryResponse);
so do this */
query.send(function(response) {
visuals(response, myObject);
});
}
function whichDrop(e) {
// Find which dropdown was changed, get it's value, find the index of the graphArray.ID it belongs to and redraw the graph
if (e.target !== e.currentTarget) {
var changedItem = e.target.id;
}
e.stopPropagation();
var findID = changedItem.substr(0, changedItem.length - 4);
arrayIndex = graphArray.findIndex(x => x.ID == findID);
var e = document.getElementById(changedItem);
var chosenGraph = e.options[e.selectedIndex].value;
graphArray[arrayIndex].graphtype = chosenGraph;
drawGraphs(graphArray[arrayIndex]);
}
function visuals(response, myObject) {
// Create the data table and draw both the table and graph
myObject.datatable = response.getDataTable();
drawTables(myObject);
drawGraphs(myObject);
}
function drawTables(myObject) {
// Draw the table
var tableArea = myObject.ID + "_table_div";
var cssClassNames = {
'headerRow': 'header-css',
'headerCell': 'border-css'
};
theTables = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: tableArea,
dataTable: myObject.datatable,
options: {
'allowHtml': true,
'cssClassNames': cssClassNames
}
});
theTables.draw();
}
function drawGraphs(myObject) {
// Draw the graph
var graphArea = myObject.ID + "_graph_div";
var chartType = myObject.graphtype + "Chart";
theGraphs = new google.visualization.ChartWrapper({
chartType: chartType,
containerId: graphArea,
dataTable: myObject.datatable,
// May have to use IF or SWITCH statements depending on chartType
options: {
height: 400,
hAxis: {
maxTextLines: 4, // maximum number of lines to wrap to
maxAlternation: 4, // maximum layers of labels (setting this higher than 1 allows labels to stack over/under each other)
minTextSpacing: 1, // minimum space in pixels between adjacent labels
},
textStyle: {
fontSize: 9
}
}
});
theGraphs.draw();
}
function transposeDataTable(myObject) {
// Transpose the datatable
dataTable = myObject.datatable;
// Toggle rotated boolean
myObject.rotated = !myObject.rotated;
// Rotate the datatable
var rows = []; //the row tip becomes the column header and the rest become
for (var rowIdx = 0; rowIdx < dataTable.getNumberOfRows(); rowIdx++) {
var rowData = [];
for (var colIdx = 0; colIdx < dataTable.getNumberOfColumns(); colIdx++) {
rowData.push(dataTable.getValue(rowIdx, colIdx));
}
rows.push(rowData);
}
var newTB = new google.visualization.DataTable();
newTB.addColumn('string', dataTable.getColumnLabel(0));
newTB.addRows(dataTable.getNumberOfColumns() - 1);
var colIdx = 1;
for (var idx = 0; idx < (dataTable.getNumberOfColumns() - 1); idx++) {
var colLabel = dataTable.getColumnLabel(colIdx);
newTB.setValue(idx, 0, colLabel);
colIdx++;
}
for (var i = 0; i < rows.length; i++) {
var rowData = rows[i];
console.log(rowData[0]);
newTB.addColumn('number', rowData[0]); //assuming the first one is always a header
var localRowIdx = 0;
for (var j = 1; j < rowData.length; j++) {
newTB.setValue(localRowIdx, (i + 1), rowData[j]);
localRowIdx++;
}
}
return newTB;
}
function createObject(ID, sheet, GID, datatable, graphtype, rotated) {
// Create the data objects and push them to the graphArray array
graphArray.push({
ID: ID,
sheet: sheet,
GID: GID,
datatable: datatable,
graphtype: graphtype,
rotated: rotated,
});
}
})();
I think that you are looking for 'ready' event. https://developers.google.com/chart/interactive/docs/events#the-ready-event
I abandoned what I was trying to do, which was to step through a list of various chart types to see what would be the best for what I wanted to display.
One of the things I wanted to look at was to create PNGs of the various charts. But, I ran foul of the "ready" event handlers again.
Just before I drew the charts I used
google.visualization.events.addListener(theGraphs, 'ready', function() {
document.getElementById(imgLink).innerHTML = 'Printable Graph';
});
but I was getting "Cannot read property 'getImageURI' of null" errors.
Presumably because of the loop the drawing of these graphs is in, it was running too fast for the event handler to catch?
I tried removing the event handler after the drawing of the charts using
google.visualization.events.removeListener(theGraphs);
and even
google.visualization.events.removeAllListeners(theGraphs);
I had thought of doing something like trying to count the number of times the event was triggered and comparing that to the number of times the function was called but went for a simpler, but probably not the best method, of adding a setTimeout function.
setTimeout(function() {
document.getElementById(imgLink).innerHTML = 'Printable Graph';
}, 100);
theGraphs.draw();
Probably not the most elegant solution, but the delay of just 1/10 of a second made the problems I've been having go away.
https://jsfiddle.net/brisray/z49jw264/706/
setTimeout(function() {
document.getElementById(imgLink).innerHTML = '<a target="_blank" href="' + theGraphs.getChart().getImageURI() + '">Printable Graph</a>';
}, 100);
theGraphs.draw();

Javascript array shows in console, but i cant access any properties in loops

I really try my damndest not to ask, but i have to at this point before I tear my hair out.
By the time the js interpreter gets to this particular method, I can print it to the console no problem, it is an array of "event" objects. From FireBug I can see it, but when I try to set a loop to do anything with this array its as if it doesn't exist. I am absolutely baffled......
A few things:
I am a newbie, I have tried a for(var index in list) loop, to no avail, I have also tried a regular old for(var i = 0; i < listIn.length; i++), and I also tried to get the size of the local variable by setting var size = listIn.length.
As soon as I try to loop through it I get nothing, but I can access all the objects inside it from the FireBug console no problem. Please help, even just giving me a little hint on where I should be looking would be great.
As for the array itself, I have no problems with getting an array back from PHP in the form of: [{"Event_Id":"9", "Title":"none"}, etc etc ]
Here is my code from my main launcher JavaScript file. I will also post a sample of the JSON data that is returned. I fear that I may be overextending myself by creating a massive object in the first place called content, which is meant to hold properties such as DOM strings, settings, and common methods, but so far everything else is working.
The init() function is called when the body onload is called on the corresponding html page, and during the call to setAllEvents and setEventNavigation I am lost.
And just to add, I am trying to learn JavaScript fundamentals before I ever touch jQuery.
Thanks
var dom, S, M, currentArray, buttonArray, typesArray, topicsArray;
content = {
domElements: {},
settings: {
allContent: {},
urlList: {
allURL: "../PHP/getEventsListView.php",
typesURL: "../PHP/getTypes.php",
topicsURL: "../PHP/getTopics.php"
},
eventObjArray: [],
buttonObjArray: [],
eventTypesArray: [],
eventTopicsArray: []
},
methods: {
allCallBack: function (j) {
S.allContent = JSON.parse(j);
var list = S.allContent;
for (var index in list) {
var event = new Event(list[index]);
S.eventObjArray.push(event);
}
},
topicsCallBack: function(j) {
S.eventTopicsArray = j;
var list = JSON.parse(S.eventTopicsArray);
topicsArray = list;
M.populateTopicsDropDown(list);
},
typesCallBack: function(j) {
S.eventTypesArray = j;
var list = JSON.parse(S.eventTypesArray);
typesArray = list;
M.populateTypesDropDown(list);
},
ajax: function (url, callback) {
getAjax(url, callback);
},
testList: function (listIn) {
// test method
},
setAllEvents: function (listIn) {
// HERE IS THE PROBLEM WITH THIS ARRAY
console.log("shall we?");
for(var index in listIn) {
console.log(listIn[index]);
}
},
getAllEvents: function () {
return currentArray;
},
setAllButtons: function (listIn) {
buttonArray = listIn;
},
getAllButtons: function () {
return buttonArray;
},
setEventNavigation: function(current) {
// SAME ISSUE AS ABOVE
var l = current.length;
//console.log("length " + l);
var counter = 0;
var endIndex = l - 1;
if (current.length < 4) {
switch (l) {
case 2:
var first = current[0];
var second = current[1];
first.setNextEvent(second);
second.setPreviousEvent(first);
break;
case 3:
var first = current[0];
var second = current[1];
var third = current[2];
first.setNextEvent(second);
second.setPreviousEvent(first);
second.setNextEvent(third);
third.setPreviousEvent(second);
break;
default:
break;
}
} else {
// do something
}
},
populateTopicsDropDown: function(listTopics) {
//console.log("inside topics drop");
//console.log(listTopics);
var topicsDropDown = document.getElementById("eventTopicListBox");
for(var index in listTopics) {
var op = document.createElement("option");
op.setAttribute("id", "dd" + index);
op.innerHTML = listTopics[index].Main_Topic;
topicsDropDown.appendChild(op);
}
},
populateTypesDropDown: function(listTypes) {
//console.log("inside types drodown");
//console.log(listTypes);
var typesDropDown = document.getElementById("eventTypeListBox");
for(var index2 in listTypes) {
var op2 = document.createElement("option");
op2.setAttribute("id", "dd2" + index2);
op2.innerHTML = listTypes[index2].Main_Type;
typesDropDown.appendChild(op2);
}
}
},
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, M.allCallBack);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
M.ajax(S.urlList.topicsURL, M.topicsCallBack);
M.ajax(S.urlList.typesURL, M.typesCallBack);
}
};
The problem you have is that currentArray gets its value asynchronously, which means you are calling setAllEvents too soon. At that moment the allCallBack function has not yet been executed. That happens only after the current running code has completed (until call stack becomes emtpy), and the ajax request triggers the callback.
So you should call setAllEvents and any other code that depends on currentArray only when the Ajax call has completed.
NB: The reason that it works in the console is that by the time you request the value from the console, the ajax call has already returned the response.
Without having looked at the rest of your code, and any other problems that it might have, this solves the issue you have:
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, function (j) {
// Note that all the rest of the code is moved in this call back
// function, so that it only executes when the Ajax response is
// available:
M.allCallBack(j);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
// Note that you will need to take care with the following asynchronous
// calls as well: their effect is only available when the Ajax
// callback is triggered:
M.ajax(S.urlList.topicsURL, M.topicsCallBack); //
M.ajax(S.urlList.typesURL, M.typesCallBack);
});
}

Can't add new name and value to JSON object dynamically with condition using JavaScript

I can't add new name and value ff. this given condition:
$.each(names, function (i, name) {
$.get('https://www.example.com/path/' + name, function (data) {
var arrNow = CSVToArray(data, ',');
allArr.push(arrNow);
counter++;
if (counter === names.length) {
for (var j = 0; j < allArr.length; j++) {
for (var k = 1; k < allArr[j].length; k++) {
//console.log(allArr[j][k][0] + ': ' + allArr[j][k][1]);
//var f = moment(allArr[j][k][0]).format('lll');
var f = allArr[j][k][0];
json.push({
"datetime": f
});
if (j == 0) {
if (json[k].datetime === allArr[0][k][0]) {
var newAtt = "water_actual";
var newValue = allArr[0][k][1];
json[k][newAtt] = newValue;
}
}
if (j == 1) {
if (json[k].datetime === allArr[1][k][0]) {
var newAtt = "rainfall_actual";
var newValue = allArr[1][k][1];
json[k][newAtt] = newValue;
}
}if (j == 2) {
if (json[k].datetime == allArr[2][k][0]) {
var newAtt = "forecast_water";
var newValue = allArr[2][k][1];
json[k][newAtt] = newValue;
}
}
}
}
};
});
});
I was able to add a new namewater_actual and its value using if statement. If the datetime from the json object matches to the array value(date and time), I'd like to add it with its specific name as stated above. But I can't seem to make it work.
Here's the fiddle.
If I may provide some general feedback: it's probably good practice to simplify your code to the minimum example that reproduces your problem. Not only can that drastically increase your chances of fixing it yourself, it also increases the odds that you'll get help here.
With that in mind, consider the basic structure of what you're trying here:
var someNames = ["foo", "bar"];
var allTheData = [{
"aardvark": true
}];
$.each(someNames, function (i, name) {
$.get('http://example.com/api/' + name, function (data) {
data.aNewProperty = 'wombat';
allTheData.push(data);
});
});
console.log(allTheData);
Here, $.each iterates through everything in someNames and then proceeds immediately to the console.log statement. For all we know, each individual API call ($.get) could take seconds, or minutes. By this time we've already tried to use the contents of allTheData, which may or may not have been modified.
To avoid this sort of thing in legacy JavaScript we can make use of the callback already provided by $.get:
$.get('http://example.com/api/' + name, function (data) {
data.aNewProperty = 'wombat';
console.log(data);
});
Inside the callback, we know for sure that the API request has already completed (although the above assumes that it succeeded, which is a whole other kettle of fish). This would output the result of each API request as the responses arrive, though not necessarily in the order you'd expect!
JavaScript's asynchronous nature tended to lead in the past to a whole lot of callbacks. With the advent of ES6 we have some more options available to us, especially promises.

Load dictionary file with ajax and don't crash iPhone Mobile Safari

I have a web application where I load (via ajax) a dictionary file (1MB) into the javascript array. I found the reason why the Mobile Safari crashes after 10 seconds. But now what I'm wondering is how do I get around this issue?
On the link above the answer suggest using setInterval, but this would mean I would have to have a dictionary file chunked into pieces and have them loaded one by one. This surely could be done, but I would have to make a lot of chunks taking into account the internet speed and too many requests would take forever for the page to load (and if I make the chunks too big it could happen that some mobile users wouldn't be able to download the chunk in a given 10second period).
So, my question is: has anyone encountered this kind of problem and how did you go about it? A general push in the right direction is appreciated.
edit:
This is the js code which I use to load the dictionary:
var dict = new Trie();
$.ajax({
url: 'data/dictionary_342k_uppercase.txt',
async: true,
success: function (data) {
var words = data.split('\n');
for (var i = words.length - 1; i >= 0; i--) {
dict.insert(words[i]);
}
},
error: function(){
$('#loading-message').text("Problem s rječnikom");
}
});
Trie.js:
function Trie () {
var ALPHABET_SIZE = 30;
var ASCII_OFFSET = 'A'.charCodeAt();
this.children = null;
this.isEndOfWord = false;
this.contains = function (str) {
var curNode = this;
for (var i = 0; i < str.length; i++) {
var idx = str.charCodeAt(i) - ASCII_OFFSET;
if (curNode.children && curNode.children[idx]) {
curNode = curNode.children[idx];
} else {
return false;
}
}
return curNode.isEndOfWord;
}
this.has = function (ch) {
if (this.children) {
return this.children[ch.charCodeAt() - ASCII_OFFSET] != undefined;
}
return false;
}
this.next = function (ch) {
if (this.children) {
return this.children[ch.charCodeAt() - ASCII_OFFSET];
}
return undefined;
}
this.insert = function (str) {
var curNode = this;
for (var i = 0; i < str.length; i++) {
var idx = str.charCodeAt(i) - ASCII_OFFSET;
if (curNode.children == null) {
curNode.children = new Array(ALPHABET_SIZE);
curNode = curNode.children[idx] = new Trie();
} else if (curNode.children[idx]) {
curNode = curNode.children[idx];
} else {
curNode = curNode.children[idx] = new Trie();
}
}
curNode.isEndOfWord = true;
return curNode;
}
}
This is a very common issue once you start doing processing in JS. If the Mobile Safari issue is the cause then what you want to do is figure out where the CPU time is going here.
I'm assuming it's the dict.insert() loop and not the data.split() call (that would be a bit more difficult to manage).
The idea here is to split up the dict.insert() loop into functional blocks that can be called asynchronously in a sequenced loop (which is what the setupBuildActions function does). After the first block each subsequent block is called via setTimeout, which effectively resets the function-time counter in the JS runtime (which seems to be what's killing your process).
Using the Sequencer function means you also keep control of the order in which the functions are run (they always run in the sequence they are generated in here and no two or more functions are scheduled for execution at the same time). This is much more effective than firing off thousands of setTimeout calls without callbacks. Your code retains control over the order of execution (which also means you can make changes during execution) and the JS runtime isn't overloaded with scheduled execution requests.
You might also want to check the node project at https://github.com/michiel/sequencer-js for more sequencing examples and http://ejohn.org/blog/how-javascript-timers-work/ for an explanation on setTimeout on different platforms.
var dict = new Trie();
// These vars are accessible from all the other functions we're setting up and
// running here
var BLOCKSIZE = 500;
var words = [];
var buildActions = [];
function Sequencer(funcs) {
(function() {
if (funcs.length !== 0) {
funcs.shift()(arguments.callee);
}
})();
}
// Build an Array with functions that can be called async (using setTimeout)
function setupBuildActions() {
for (var offset=0; offset<words.length; offset+= BLOCKSIZE) {
buildActions.push((function(offset) {
return function(callback) {
for (var i=offset; i < offset + BLOCKSIZE ; i++) {
if (words[i] !== null) { // ugly check for code brevity
dict.insert(words[i]);
}
}
// This releases control before running the next dict.insert loop
setTimeout(callback, 0);
};
})(offset));
}
}
$.ajax({
url: 'data/dictionary_342k_uppercase.txt',
async: true,
success: function (data) {
// You might want to split and setup these calls
// in a setTimeout if the problem persists and you need to narrow it down
words = data.split('\n');
setupBuildActions();
new Sequencer(buildActions);
},
error: function(){
$('#loading-message').text("Problem s rječnikom");
}
});
Here's an example using setTimeout to defer the actual insertion of words into your trie. It breaks up the original string into batches, and uses setTimeout to defer processing of inserting each batch of words. The batch size in my example is 5 words.
The actual batch insertion happens as subsequent event handlers in the browser.
It's possible that just breaking the words up into batches might take too long. If you hit this problem, remember you can chain setTimeout() calls, eg iterating for a while then using setTimeout to schedule another event to iterate over some more, then setTimeout again, etc.
function addBatch(batch)
{
console.log("Processing batch:");
for (var i = 0; i < batch.length; i++)
console.log(batch[i]);
console.log("Return from processing batch");
}
var str = "alpha\nbravo\ncharlie\ndelta\necho\nfoxtrot\n" +
"golf\nhotel\nindia\njuliet\nkilo\nlima\n" +
"mike\nnovember\noscar\npapa\nquebec\n" +
"romeo\nsierra\ntango\nuniform\n" +
"victor\nwhiskey\nxray\nyankee\nzulu";
var batch = []
var wordend;
for (var wordstart = 0; wordstart < str.length; wordstart = wordend+1)
{
wordend = str.indexOf("\n", wordstart);
if (wordend < 0)
wordend = str.length;
var word = str.substring(wordstart, wordend);
batch.push(word);
if (batch.length > 5)
{
setTimeout(addBatch, 0, batch);
batch = [ ];
}
}
setTimeout(addBatch, 0, batch);
batch = [ ];

Async calls to service in javascript

In my project I am calling same service for more than 2-3 times for finding distance & time for my route in javascript using cloudmode service.
I am having one polyline, I am getting each point of polyline & passing two consecutive points to service to get response from it.
What I am doing is
function showPointsRoutes(e)
{
var a = e.target.getLatLngs();
for(var i = 1 ; i < a.length ; i++)
{
var as ="http://routes.cloudmade.com/BC9A493B41014CAABB98F0471D759707/api/0.3/" + a[i-1].lat+","+a[i-1].lng+","+a[i].lat+","+a[i].lng + "/car/shortest.js?callback=getRouteResponse";
addScript(as);
}
}
function getRouteResponse(response)
{
mytimeArray.push[response.route_summary.total_time];
myDistancArray.push[response.route_summary.total_distance];
}
function addScript(url)
{
var script = document.createElement('script');
script.type="text/javascript";
script.src=url;
document.getElementsByTagName('head') [0].appendChild(script);
}
But sometimes what happens is that response for some requests comes late.
due to this I am not getting proper times & distance between points.
Can any one suggest some way so that I get values in array as sequence in which request was made.
The reason they give you different callback names is so that you can differentiate requests by using a different callback for each one. Try something like this:
Note: #Rodrigo Assis's suggestion would be better in this case since the API supports this. Code below demonstrates a way to handle this when the API forces using multiple requests.
function showPointsRoutes(e)
{
var a = e.target.getLatLngs();
for(var i = 1 ; i < a.length ; i++)
requestRoute(i, a[i-1], a[i]);
}
function requestRoute(i, a, b)
{
window["getRouteResponse" + i] = function(response)
{
mytimeArray[i] = response.route_summary.total_time;
myDistancArray[i] = response.route_summary.total_distance;
};
var as ="http://routes.cloudmade.com/BC9A493B41014CAABB98F0471D759707/api/0.3/" + a.lat+","+a.lng+","+b.lat+","+b.lng + "/car/shortest.js?callback=getRouteResponse" + i;
addScript(as);
}
function addScript(url)
{
var script = document.createElement('script');
script.type="text/javascript";
script.src=url;
document.getElementsByTagName('head') [0].appendChild(script);
}

Categories

Resources