This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
Created a fiddle for this as it is so simple but yet it doesn't work;
var url = 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json';
function getData (url) {
return $.ajax({
'type': "POST",
'url': url
});
};
$(document).ready(function(){
var a = null;
getData(url).done(function(data){ a = data; });
alert(a);
});
early morning perhaps?
Fiddle: https://jsfiddle.net/nextgenmappinginc/r88356tu/
Goal:
I have multiple local files which contain geojson data. Which I will be returned to me as an array. I want to loop through these create objects and push these objects into an array. Then from the new array created by all of these ajax calls. I want to pass this array to a function that will execute open layers code.
updated and completed different fiddle
https://jsfiddle.net/nextgenmappinginc/x1yasngy/
But. Problem remains. Even when you pass through ASYNC The function is only fired upon request. Then it remains in the function. So technically why can't it pass it to another function that can then console it?
In the fiddle you can simply change the urls so that you can get request response
//var url = 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json';
var url = {url : 'clientData/10BC99F2-05FD-4847-A277-2979C83BB42A/geojson/E36CC45E-C1B8-4C26-A714-EBA91ACE7C1C.js'}
var files = [];
files.push(url);
function getData (files) {
var fileObjects = [];
for (i=0; i<files.length; i++){
$.ajax({
'type': "GET",
'url': files[i].url,
success: function (response){
fileObjects.push(response);
}
});
}
consoleMe(fileObjects);
}
function consoleMe(data){
console.log(data);
}
getData(files);
add async:false, in your ajax code. Remove this line
getData(url).done(function(data){ a = data; });
and add below line
getData(url).done(function(data){ a = data; });
Try below example this will work for sure
var url = 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json';
function getData (url) {
return $.ajax({
'type': "POST",
async:false,
'url': url
});
};
$(document).ready(function(){
var a = null;
a = getData(url);
console.log(a);
alert(a);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
You want to "get" data but you do a post request to the API. Secondly .done is an asynchronous function. It will be execute when the API sends you the data.
Code
var url = 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json';
function getData (url) {
return $.ajax({
'type': "get",
'url': url
});
};
$(document).ready(function(){
getData(url).done(function(data){
// here you have access to data
alert(data)
});
});
Related
I have an Ajax request that fetch data in database.
These data may vary in function of the action that calls the ajax request.
Each time the Ajax request is called, I want some ot these datas to be pushed in a javascript array declared outside of the Ajax function.
The problem is, each time Ajax is called, my function manage to put the wanted data in the array but erases the previous data.
Here is the script :
<script>
let myArray = [];
function fetchWeeksForViewportWidth(startDate) {
//AJAX
$.ajax({
method: "GET",
url: "{{path('days_json')}}",
data: {
//some data
},
success: function (data) {
let trParents = document.getElementsByClassName('project-assignment');
$.each(trParents, function(key, parent) {
let assId = parent.dataset.assignmentId;
myArray[assId] = [];
$.each(data['days'], function(key, value) {
myArray[assId][value.code] = 0;
//some other treatment
if(value.code in data['game']) {
myArray[assId][value.code] = data['game'][value.code];
});
});
});
},
error: function() {
//handle error
console.log("error")
}
});
}
$(document).ready( function () {
function displayArray(){
console.log(myArray);
setTimeout(displayArray, 5000);
}
displayArray();
});
</script>
Any idea why new data don't add to the ones from previous ajax calls but keep replacing them ?
Instead of assignment
myArray[assId][value.code] = 0;
try the push() function of the array
myArray[assId].push(0);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
Below is my code in a JavaScript file that is included in an HTML file.
When I console.log msg I can see there are 100 items in the array (see screenshot), however dataArray is still empty after the last console.log(dataArray).
I don't get any errors or things like that so it's hard for me to debug this.
function loadPosts() {
var dataArray = new Array();
var root = 'https://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/',
method: 'GET',
success:function(msg){
dataArray = msg;
}
});
console.log(dataArray);
}
window.onload = loadPosts;
Your console.log is executed before the AJAX request's success handler is called, otherwise it looks correct. You can add a console.log(dataArray) after you assign dataArray = msg; in the callback to see it.
AJAX is asynchronous by nature, so what is happening is you are executing:
Ajax call
console.log(dataArray)
Success callback
For the desired output you should move your console log into the success handler:
function loadPosts() {
var dataArray = new Array();
var root = 'https://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/',
method: 'GET',
success:function(msg){
dataArray = msg;
// act on data array
console.log(dataArray);
}
});
}
I would also recommend moving from the success/error callbacks to Promises, since the callbacks are deprecated and removed as of jQuery 3. This would change your code like so:
function loadPosts() {
var root = 'https://jsonplaceholder.typicode.com';
return $.ajax({
url: root + '/posts/',
method: 'GET'
});
}
loadPosts().then(function(data) {
// resolve promise handler
// do something with your data
console.log(data);
}, function(err) {
// rejected promise handler (failure)
console.error(data);
});
For more info:
jQuery Ajax Documentation
Promise Spec
Check this code below :
function loadPosts() {
var dataArray = [];
var root = 'https://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/',
method: 'GET',
success:function(msg){
console.log('First');
dataArray = msg;
}
});
console.log('Second');
console.log(dataArray);
}
window.onload = loadPosts;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
you will see that the order of execution.
If you need to treat dataArray after his assignment, in success callback, you need to call a function and pass as argument the new dataArray.
console.log is executed before ajax call is completed. so make asynchronous request.
function loadPosts() {
var dataArray = new Array();
var root = 'https://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/',
method: 'GET',
async:false,// <--
success:function(msg){
dataArray = msg;
}
});
console.log(dataArray);
} window.onload = loadPosts;
I'm writing something to get all the layers names from my GeoServer. This is my code:
function getData() {
return $.ajax({
url: "http://localhost:8080/geoserver/ows?service=wms&version=1.1.0&request=GetCapabilities",
type: 'GET'
});
}
function onComplete(data) {
var parser = new ol.format.WMSCapabilities();
var result = parser.read(data.responseText);
var layersArray = result.Capability.Layer.Layer;
layersNameArray = [];
for(i=0;i<layersArray.length;i++){
layersNameArray.push(layersArray[i].Name)
}
return layersNameArray
}
getData().done(onComplete)
I'm far from an expert with asynchronous calls, but I think this one is supposed to work. If I stock the getData() result in a variable and run the onComplete() function line by line, the code works. But when I run the code with getData().done(onComplete), it always fails at the var result = parser.read(data.responseText);line with Assertion error: Failure.
Any idea why this isn't working ?
Edit:
This code works, but nothing is returned. I want the function to output the layersNameArrayvariable. How should I proceed ?
function getData() {
$.ajax({
url: "http://localhost:8080/geoserver/ows?service=wms&version=1.1.0&request=GetCapabilities",
type: 'GET',
success: function(response) {
var parser = new ol.format.WMSCapabilities();
var result = parser.read(response);
var layersArray = result.Capability.Layer.Layer;
layersNameArray = [];
for(i=0;i<layersArray.length;i++){
layersNameArray.push(layersArray[i].Name)
}
return layersNameArray
}
});
}
You can make use of the Jquery callback feature,
make a call to your function this way,
getData(function(responsefromAjax){
alert('the response from ajax is :' +responsefromAjax);
// what ever logic that needs to run using this ajax data
});
And the make change to your method this way.
function getData(callback) { // passing the function as parameter
$.ajax({
url: "http://localhost:8080/geoserver/ows?service=wms&version=1.1.0&request=GetCapabilities",
type: 'GET',
success: function(response) {
var parser = new ol.format.WMSCapabilities();
var result = parser.read(response);
var layersArray = result.Capability.Layer.Layer;
layersNameArray = [];
for(i=0;i<layersArray.length;i++){
layersNameArray.push(layersArray[i].Name)
}
callback(layersNameArray); //this will execute your function defined during the function call. As you have passed the function as parameter.
}
});
}
Let me know if this helps
I have created a small JavaScript application with the following function that calls a function to retrieve JSON data:
var months = function getMonths(){
$.getJSON("app/data/Cars/12Months", function (some_data) {
if (some_data == null) {
return false;
}
var months_data = new Array();
var value_data = new Array();
$.each(some_data, function(index, value) {
months_data.push(index);
value_data.push(value);
});
return[months_data,value_data];
});
}
I have then created, in the same file, another function that does something when a specific page is loaded. In this function the variable 'months' is passed to the variable 'result'.
$(document).on('pageshow', '#chartCar', function(){
$(document).ready(function() {
var result = months;
var date = result[0];
var values = result[1];
//more code here...
});
}
the problem is that, based on the debugger, the getMonths() function works fine and produces the expected output, but the 'result' variable in the second function can't obtain the values passed to it by the variable 'months'. Do you know how to solve this issue?
The problem is that you $.getJSON() function is asynchronous, so your data gets loaded later then you read it. There're two workarounds:
1. Replace your $.getJSON with $.ajax and setting async: false;
2. Put your code in $.getJSON callback:
var months = function getMonths(){
$.getJSON("app/data/Cars/12Months", function (some_data) {
if (some_data == null) {
return false;
}
var months_data = new Array();
var value_data = new Array();
$.each(some_data, function(index, value) {
months_data.push(index);
value_data.push(value);
});
var date = months_data;
var values = value_data;
//more code here..
})
}
There must be a syntax error.
replace
});
}
With
});
});
$.getJSON() is a wrapper around $.ajax which is async by default. But you treat it like a sync call.
You can use $.ajaxSetup()
$.ajaxSetup( { "async": false } );
$.getJSON(...)
$.ajaxSetup( { "async": true } );
or use $.ajax with async: false
$.ajax({
type: 'GET',
url: 'app/data/Cars/12Months',
dataType: 'json',
async: false,
success: function(some_data) {
//your code goes here
}
});
or if possible change the behavior of your app so that you process your data in a callback function.
I have an issue with a method ive created for an object ive created. one of the methods requires a callback to another method. the problem is i cant add the data to the object that called the method. it keeps coming back as undefined. otherwise when i send the data to the console it is correct. how can i get the data back to the method?
var blogObject = new Object();
var following = [...];
//get posts from those blogs
blogObject.getPosts = function () {
var followersBlogArray = new Array();
for (var i = 0; i < this.following.length;i++){
var followersBlog = new Object();
// get construct blog url
var complete_blog_url = ...;
i call the getAvatar function here sending the current user on the following array with it.
followersBlog.avatar = blogObject.getAvatar(this.following[i]);
that part goes smoothly
followersBlogArray.push(followersBlog);
}
this.followersBlogArray = followersBlogArray;
}
here is the function that gets called with the current user in following array
this function calls an ajax function
blogObject.getAvatar = function (data) {
console.log("get avatar");
var url = "..."
this ajax function does its work and has a callback function of showAvatar
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
this function gets called no problem when getAvatar is called. i cant however get it to add the data to the followersBlog object.
blogObject.showAvatar = function (avatar) {
return avatar
}
everything in here works fine but i cant get the showAvatar function to add to my followersBlog object. ive tried
blogObject.showAvatar = function (avatar) {
this.followersBlog.avatar = avatar;
return avatar
}
that didnt work of course. it shows up as undefined. can anyone help?
so somethings like...
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
complete: function () {
this.avatar = data;
}
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
Welcome to the world of asynchronous programming.
You need to account for the fact that $.ajax() will not return a value immediately, and Javascript engines will not wait for it to complete before moving on to the next line of code.
To fix this, you'll need to refactor your code and provide a callback for your AJAX call, which will call the code that you want to execute upon receiving a response from $.ajax(). This callback should be passed in as the complete argument for $.ajax().
The correct option for setting the JSONP callback is jsonpCallback. The recommendation from the API for .ajax(...) is to set it as a function.
{
// ...
jsonpCallback: function (returnedData) {
blogObject.showAvatar(returnedData);
},
// ...
}