Why doesn't the array get populated with the ajax repsonse? - javascript

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;

Related

ajax call is failing when called in a function inside a for loop

I am trying to call an API and get and display all orders and then for each order to call another endpoint which returns the details about the worker who has placed the order and display these details along with the order details.
Using Ajax, I call the first endpoint which returns all the order. I looped through all returned orders and display the details about each order. Inside the loop I call a function which take as parameter the WorkerId (getWorker(WorkerId). This function is created outside the for loop and contains another ajax call to the second API endpoint, which returns the details about the worker.
var app = {}; // creating a empty object to hold the data
// getAllOrders method will make the Ajax request to the API
app.getAllOrders = function() {
$.ajax({
url: 'https://www.hatchways.io/api/assessment/work_orders',
method: 'GET',
dataType: 'json',
data: {
format: 'json'
},
success: function(result) {
console.log('Ajax is working.');
app.displayAllOrders(result);
},
error: function(error) {
console.log('Something went wrong.');
console.log(error);
}
});
}; //end app.getAllOrders function
app.getAllOrders();
app.displayAllOrders = function(allOrders) {
console.log(allOrders);
// getWorker method will make the Ajax request to the API
app.getWorker = function(id) {
console.log('Ajax is working.');
$.ajax({
url: 'https://www.hatchways.io/api/assessment/workers/' + id,
method: 'GET',
dataType: 'json',
data: {
format: 'json'
},
success: function(result) {
console.log('Ajax is working.');
app.workersInfo(result);
},
error: function(error) {
console.log('Something went wrong.');
console.log(error);
}
});
}; //end app.getWorker function
// creating a method to inject our data into the DOM
app.workersInfo = function(worker) {
console.log(worker);
// Creating var for each piece of data for worker id
var comp = $('<p>').text(worker.worker.companyName);
var nameWorker = $('<p>').text(worker.worker.name);
var email = $('<p>').text(worker.worker.email);
var workerId = $('<p>').text(worker.worker.id);
var workerInfo = $('<div>').append(nameWorker, comp, email, workerId);
$('#allOrders').append(workerInfo);
}; //end app.workersInfo function
for (var i = 0; i < allOrders.orders.length; i++) {
// creating var for each piece of data for order
var id = $('<p>').text(allOrders.orders[i].id);
var nameOrder = $('<h3>').text(allOrders.orders[i].name);
var desc = $('<p>').text(allOrders.orders[i].description);
var deadline = $('<p>').text(allOrders.orders[i].deadline);
var workerId = $('<p>').text(allOrders.orders[i].workerId);
// appending in div all info for the order
var orderInfo = $('<div>').addClass('orderInfo').append(nameOrder, id, desc, deadline, workerId);
// appending in div all info for worker
$('#allOrders').append(orderInfo);
// call getWorker function to display worker
var myWorkerId = allOrders.orders[i].workerId;
app.getWorker(myWorkerId);
};
};
When getWorker(myWorkerId) is called, the Ajax call inside it is not called. This is called only after iterating through the loop is done. I tried with another function inside getWorker() instead of Ajax call and this is working. Please let me know if you can spot what I am doing wrong and how this can be fixed.

jquery global variable ajax returns null [duplicate]

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)
});
});

AJAX callback to retrieve layers name from GeoServer fails with an assertion error

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

jQuery AJAX issue? Or JS OOP scope issue?

I am trying to create a database handler class in javascript. I would like to call the class by simply using:
var databaseHandler = new DatabaseHandler();
result = databaseHandler.getResult("SELECT * FROM login");
I have created the class and used a callback for the ajax function (so as to wait for the ajax result to be returned). But all I am still receiving "undefined" as my result. If I use console.log(a) inside of the onComplete function, I get an array of the intended results.
(function(window){
//Database class
function DatabaseHandler(){
//Query
this.query = function(query, whenDone){
request = $.ajax({
url: "../optiMizeDashboards/php/DatabaseQuery.php",
type: "POST",
data: {query : query},
dataType: "JSON"
});
request.done(function(output) {
whenDone(output);
});
request.fail(function(jqXHR, textStatus) {
console.log(textStatus);
});
};
//Get result
this.getResult = function(query){
this.query(query, this.onComplete);
};
//Ajax callback
this.onComplete = function(a){
return a;
};
}
//Make available to global scope
window.DatabaseHandler = DatabaseHandler;
}(window))
My question is: Is this something to do with the variable scope, or the way that ajax works? I have read all the answers explaining that ajax is ASYNC and I thought I had handled that by using a callback function "onComplete"
Any help on this topic would be greatly appreciated!
You will not be able to return result immediately from calling getResult because underlying jQuery POST request is Asynchronous, instead you need to be passing a callback function which eventually will receive a result from server.
something like that:
(function(window){
//Database class
function DatabaseHandler(){
//Query
this.query = function(query, whenDone){
request = $.ajax({
url: "../optiMizeDashboards/php/DatabaseQuery.php",
type: "POST",
data: {query : query},
dataType: "JSON"
});
request.done(function(output) {
whenDone(output);
});
request.fail(function(jqXHR, textStatus) {
console.log(textStatus);
});
};
//Get result
this.getResult = function(query, callback){
this.query(query, callback);
};
}
//Make available to global scope
window.DatabaseHandler = DatabaseHandler;
}(window))
// then use it like so
var databaseHandler = new DatabaseHandler();
result = databaseHandler.getResult("SELECT * FROM login", function(data) {
//do something with data
});
PS: exposing direct SQL access to the databse on the client is very dangerous though, and I would not recommend doing that

Assign value to global variable using $.Ajax (JQuery)

I am creating new functionality where I build a grid based on Json data returned from Ajax. I have decided I want to encapsulate this functionality within a function, so when I add/update/delete, I can on success retrieve a new representation of the data.
The problem I am having is I want to fill a global array but once my function that uses AJAX ends, I have an Array but no data. This isn't a problem when all the code is within the AJAX call but once I try to separate this in to its own function, it doesn't work as intended.
<script type="text/javascript">
var DataArray = [];
// Use this function to fill array
function retrieveNotes() {
$.ajax({
url: "http://wks52025:82/WcfDataService.svc/GetNotesFromView()?$format=json",
type: "get",
datatype: "json",
asynch:true,
success: function (data) {
returnedData = data;
$.each(data.d, function (i, item) {
DataArray[i] = [];
DataArray[i][0] = item.NotesTitle.trim();
DataArray[i][1] = item.ProfileName.trim();
DataArray[i][2] = item.IsShared;
DataArray[i][3] = item.NameOfUser.trim();
}) // End of each loop
}
});
}
$(document).ready(function () {
retrieveNotes();
DataArray;
</script>
It's asynchronous, so you'll have to wait for the ajax call to finish before you can use the data :
function retrieveNotes() {
return $.ajax({
url: "http://wks52025:82/WcfDataService.svc/GetNotesFromView()?$format=json",
type: "get",
datatype: "json"
});
}
$(document).ready(function () {
retrieveNotes().done(function(data) {
var DataArray = [];
$.each(data.d, function (i, item) {
DataArray[i] = [];
DataArray[i][0] = item.NotesTitle.trim();
DataArray[i][1] = item.ProfileName.trim();
DataArray[i][2] = item.IsShared;
DataArray[i][3] = item.NameOfUser.trim();
});
// you can only use the data inside the done() handler,
// when the call has completed and the data is returned
});
});

Categories