Answer the question
In order to leave comments, you need to log in
How to force javascript to wait for ajax response?
Hello!
I've been banging my forehead against the wall for a couple of hours already :)
I have a database with a table that stores data about locations (fields id, location, start, end, description). The location column stores place_id from the Google Maps API , by which this API can find the location and put it on the map (with a marker).
According to the conditions of the problem, during one visit to the page, the number of records in the table can change (records can be changed, deleted or added). Therefore, it was decided that three different functions in javascript would be responsible for creating a map, creating a list of markers, and displaying these markers.
$(document).ready(function()
{
// создает карту
var map = create_map();
// создает маркеры, не отображая их
var markers = create_markers(map);
// показывает, что объекты в массиве есть (об этом читайте далее)
console.log(markers);
// показывает 0 (об этом читайте далее)
console.log(markers.length);
// включает отображение маркеров
setAllMap(map, markers);
});
function create_map() {
var mapOptions = {
center: {lat: 0, lng: 0},
zoom: 1
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
return map;
}
function create_markers(map) {
console.log("create_markers_start");
var service = new google.maps.places.PlacesService(map);
var infowindow = new google.maps.InfoWindow();
var markers = [];
$.ajax({
async: false,
url: '/index.php/locations/get_locations_list_json',
success: function(locations_json) {
console.log("create_markers___ajax_success_start");
var locations = $.parseJSON(locations_json);
$.each(locations, function(i, location_point) {
var request = {
placeId: location_point.location
};
Date.prototype.getMonthName = function() {
var month = ['Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'];
return month[this.getMonth()];
}
var desc = location_point.description;
var start_obj = new Date(location_point.start);
var start = start_obj.getMonthName() + " " + start_obj.getDate();
var end_obj = new Date(location_point.end);
var end = end_obj.getMonthName() + " " + end_obj.getDate();
service.getDetails(request, function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
markers[i] = new google.maps.Marker({
map: null,
position: place.geometry.location
});
google.maps.event.addListener(markers[i], 'click', function() {
infowindow.close();
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' +
'You\'re going to visit <u>' + place.formatted_address + '</u>' +
' <b>from</b> ' + start +
' <b>to</b> ' + end +
'<br><br>' + desc);
infowindow.open(map, this);
});
}
});
});
}
});
console.log("create_markers_end");
return markers;
}
create_markers_start
create_markers___ajax_success_start
create_markers_end
var_markers
Array[7]
0
create_markers(map, function(markers) {
console.log("in `create_markers`: markers: ");
console.log(markers);
console.log("in `create_markers`: markers.length: ");
console.log(markers.length);
// включает отображение маркеров
setAllMap(map, markers);
});
function create_markers(map, fn) {
var markers = {}
$.ajax(..., {
success: function(...) {
...
console.log("markers: ");
console.log(markers);
console.log("markers.length: ");
console.log(markers.length);
fn(markers);
}
});
}
markers:
Array[7]
markers.length:
0
in `create_markers`: markers:
Array[7]
in `create_markers`: markers.length:
0
function create_markers(map, fn) {
...
var markers_array = [];
var promises_array = [];
$.ajax({
...
success: function(...)
{
$.each(..., function(...) {
// отслеживаем состояние асинхронного запроса
var dfd;
dfd = new $.Deferred();
// это асинхронный запрос, для его правильной обработки используем промисы
service.getDetails(..., function(...) {
var marker = ...;
// по завершению формирования маркера отправляем его в массив
markers_array.push(marker);
// затем помечаем, что асинхронный запрос завершился успехом
dfd.resolve();
});
// отправляем отчет об успешном завершении очередного асинхронного запроса в массив с промисами
promises_array.push(dfd.promise());
});
// если все асинхронные вызовы завершились - вызываем callback
$.when.apply($, promises_array).then(function(){
fn(markers_array);
});
}
});
}
$(document).ready(function()
{
...
create_markers(map, function(markers_array) {
...
});
});
Answer the question
In order to leave comments, you need to log in
It is necessary to pass a callback to `create_markers`, which will be called after the data is loaded and the object with markers is filled.
function create_markers(map, fn) {
var markers = {}
$.ajax(..., {
success: function(...) {
...
fn(markers);
}
});
}
var map = create_map();
create_markers(map, function(markers) {
// показывает, что объекты в массиве есть (об этом читайте далее)
console.log(markers);
// показывает 0 (об этом читайте далее)
console.log(markers.length);
// включает отображение маркеров
setAllMap(map, markers);
});
specify async: false in ajax, but the problem is that the browser gets up until the data is loaded, i.e. at best, callbacks should be used.
Judging by the code, the markers variable is defined twice:
var markers = create_markers(map);
and then in create_markers:
var markers = [];
This second one seems to be redundant.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question