Im new to .ajax and so far so good. But I've run into an issue of, I want to run a function once I've used up all the data.
For example I have the following, i run it on 'click':
$.ajax({
url: "url.modal.tothegoods" + (nextPage),
success: function (data) {
//keeps appending data on click
},
error: function () {
alert('balls');
}
})
I've tried the ajaxcomplete function but it runs everytime i load data onto the screen.
It runs everytime i appened data .ajaxcomplete runs. I guess the questions is, how do I run a function once I have no more data to consume. So I am truly done
any tips/tricks would be greatly appreciated
The response depends on which is currently the behaviour of your server part.
If you have hand on it, the most simple solution is that it returns nothing when there is no more data to send. So you may do something as simple as this:
$.ajax({
url: "url.modal.tothegoods" + (nextPage),
success: function (data) {
if (!!data) {
//keeps appending data on click
}
},
error: function () {
alert('balls');
}
})
Related
I am working on a jquery/ajax project. On document ready, I have the following code:
$(document).ready(function () {
$.ajax({
url: '/Main/ReturnGroups/',
dataType: "json",
success: function (data) {
$('.column').each(function (index) {
let indexVar = index;
let colID = $(this).attr("id");
for (let i = 0; i < data.length; i++) {
if ($(this).attr("id") == data[i].ColumnID) {
let thisID = $(this).attr("id");
let thisGroupID = data[i].ID;
$.ajax({
url: '/Main/GetFullGroup/',
data: { groupID: thisGroupID },
success: function (html) {
$('#' + thisID).append(html); //this html inserts a portlet (JqueryUI) based element
}
});
}
}
})
},
complete: function () {
alert($('.portlet').length); //returns 0 (leads me to believe its being run before success function
AddPageProperties(); //this function is supposed to add a bunch of classes to the elements injected in the success function but doesnt actually add the classes when its here
}
});
})
It seems to me that the contents of the complete: function is running asynchronously with the success function. From my understanding the purpose of the complete function is to run once the ajax success (or error) function is completely done.
The code is iterating all the columns and returning all the groups which have the same column id in my database, then passing the groupID to another webmethod which is then querying for all tasks and using the passed in groupID only pulling the tasks that are associated to the group, then using that data to inject a partial view to place the tasks/groups in their respective locations.
Things I've tried:
-Put the AddPageProperties() function in a button click, and after the ajax is finished, click the button. This works exactly as intended.
-use ajaxStop(). While this does work as I want for document ready, once I submit another ajax request it runs the function again, thus duplicating the code. My project uses ajax requests when elements are moved around the screen so this doesnt work.
-Try and get the details of an element to see if the html is even there in the first place when the complete: function() is run. The alert in the code snippet returns 0, which leads me to believe the HTML is not there when that alert is executed.
-using the index of the each function to determine the end of the iteration and then run the function, but again does not apply classes in the function. I tried to again do an alert to see if the elements are present, but they are not.
-set async to false, but the browser just says that its deprecated and it doesnt change any behavior
Any advice on the path towards a solution is appreciated. My goal is once all the HTML is injected, then and only then run this function and never again until page is reloaded sometime later.
I would like to stick with JQuery/ajax as my project is dependent on JQuery for Bootstrap.
I have built a weather website that calls the flickr API 1st, then calls the yahoo API for the weather. The problem is that the data from the ajax call - from the yahoo API is not here in time for the page to load its content.
Some of the things I have used to try and slow the ajax call down:
setTimeout
wrapping the entire function that $.ajax(success: ) calls into another function, wrapping it in setTimeout
taking the callback function out of $.ajax(success: ), and putting into the $.ajax(complete: ) param
taking the data object that $.ajax(success: ) passes in, and copying that to another var, then going outside of ajax call and putting the function that handles the data inside of $.ajaxComplete(), passing new object var
There are more ways that I have tried to go about this, but I have been at it for 3 days and cannot find a solution. Can someone please help me here
Here is a link to the project
My Weather App On codeine.io
function RunCALL(url)
{
var comeBack = $.ajax({
url: url,
async: false,
dataType:"jsonp",
crossDomain: true,
method: 'POST',
statusCode: {
404: function() {console.log("-4-4-4-4 WE GOT 404!");},
200: function() {console.log("-2-2-2-2 WE GOT 200!");}},
success: function(data){
weatherAndFlickrReport(data);},
error: function(e) {console.log(e);}
});
}
Are you using jQuery? If so, you have to chain your callbacks. Which, at a high level, would looks something like:
//You might want to use .get or .getJSON, it's up to what response you're expecting...
$.getJSON('https://example.com/api/flickr', function(response) {
//This your callback. The URL would end up being https://example.com/api/yahoo/?criteria=lalalalala
$.getJSON('https://example.com/api/yahoo/', { criteria: response.propertyYouWant}, function(yahooResponse) {
//Do something with your response here.
});
});
Edit: I have updated your snippet with a working solution (based on the above AJAX requests) which now shows both your JSON objects ready for consuming. Looky here.
I have a piece of code I want to run after all the ajax is completed.
The function I wish to run is:
function autoContinueCart(){
$('.nextSection a:visible').click();
}
This click event runs validating script and moves to next section. Heres the main ajax.
$('#SubmitLoginOpc').click(function () {
$.ajax({
type:'POST',
url:authenticationUrl,
async:false,
cache:false,
dataType:"json",
data:'SubmitLogin=true&ajax=true&email=' + encodeURIComponent($('#login_email').val()) + '&passwd=' + encodeURIComponent($('#login_passwd').val()) + '&token=' + static_token,
success:function (jsonData) {
if (jsonData.hasError) {
//error stuff
}
else {
// update token
static_token = jsonData.token;
$('#dlv_label, #new_label').removeClass('new-l').addClass('logged-l'); // change label on delivery address section
updateNewAccountToAddressBlock();
// RESET ERROR(S) MESSAGE(S)
$('#opc_account_errors').html('').hide();
$('#opc_account_errors_invoice').html('').hide();
//It doesnt work here
//autoContinueCart();
}
},
//doesnt work here
// complete:autoContinueCart
});
return false;
});
I have put this function call in the success part, which I thought would work since it is synchronous. I also put it as complete and in .done function after the ajax call and it still runs before all the inside code is complete. The function updateNewAccountToAddressBlock(); basically makes another jquery ajax request with this type async:true, and returns json that is then used in about 10 functions or sub functions in the success call. One of these uses this data to fill out all the fields of a form. My function I am trying to call at the end is supposed to validate the info that is being populated. But no matter what I try, the validation is failing because the autoContineCart is being run before the fields are being populated. I also tried to use a callback like updateNewAccountToAddressBlock(updateAddressSelection); and then checked callback function inside of that and it also didnt work. Anyone have an idea what I could be doing wrong?
Since your call is already asynchronous, is it possible to move the processing code out of the ajax callback function? This would ensure that all of the ajax portion is complete before moving on to the processing piece.
Example:
$('#SubmitLoginOpc').click(function () {
$.ajax({
type:'POST',
url:authenticationUrl,
async:false,
cache:false,
dataType:"json",
data:'SubmitLogin=true&ajax=true&email=' + encodeURIComponent($('#login_email').val()) + '&passwd=' + encodeURIComponent($('#login_passwd').val()) + '&token=' + static_token
},
success: function(jsonData) {
$('#SubmitLoginOpc').data("some_key",jsonData);
}
//doesnt work here
// complete:autoContinueCart
});
jsonData = $('#SubmitLoginOpc').data("some_key");
if (jsonData.hasError) {
//error stuff
}
else {
// update token
static_token = jsonData.token;
$('#dlv_label, #new_label').removeClass('new-l').addClass('logged-l'); // change label on delivery address section
updateNewAccountToAddressBlock();
// RESET ERROR(S) MESSAGE(S)
$('#opc_account_errors').html('').hide();
$('#opc_account_errors_invoice').html('').hide();
//It doesnt work here
//autoContinueCart();
return false;
}
});
As the poster above said, Perhaps you could move some of the other ajax functions to run from the same js file, or move some of the Php functions to be run at the same time as the first call.
Ideally you shouldn't have to do another ajax request, because the php/whatever already has the info it needs from the client side. You should be able to send that data to other php/whatever scripts.
If you do need to do another ajax call, perhaps having the user wait a mandatory second, before you run the ajax call.
for instance:
$ajax.done(
// code
if (success)
{
setTimeout('foo', 5000);
$('#spinner').show();
}
function foo()
{
$('#spinner').hide();
//second ajax request
}
I want take some data from server and write it to global array in JavaScript. Then in document ready I want to use this array to create some new elements (options). I should have global array with this data, because after first load client can modify user interface using this data.
$(document).ready(function () {
UseAjaxQueryForFillGlobalArray();
MakingInterfaceUsingGlobalArray();
});
But I have strange behavior, when I debug page, I can see that method MakingInterfaceUsingGlobalArray working first, and just after I get data via AJAX with method UseAjaxQueryForFillGlobalArray and I don't have new interface(html options) with loaded data.
If I do like this:
UseAjaxQueryForFillGlobalArray();
$(document).ready(function () {
MakingInterfaceUsingGlobalArray();
});
Then in Firefox working fine, but in another web-browsers incorrect in first load (for example go to this page by link). But if I refreshing by F5, I have correct user interface which loaded via AJAX to global JS array.
How to fix it? Maybe I using totally incorrect way?
Added after comments:
This is my ajax function:
function UseAjaxQueryForFillGlobalArray(){
var curUserId = '<%= Master.CurrentUserDetails.Id %>';
var curLocale = '<%= Master.CurrentLocale %>';
$.ajax({
type: "POST",
url: "/segment.aspx/GetArrayForCF",
data: '{"userId":"' + curUserId + '","curLocale":"' + curLocale + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//here is I doing parse my string from server and fill arrays.
}
});
}
I think that the problem is that you don't know exactly when the first function returns, since it'a asynchronous. So you should use the array in the callback only
function UseAjaxQueryForFillGlobalArray() {
// make the call
$.post(url, data, function() {
// let's be sure that the dom is ready
$(document).ready(function () {
// use the array
MakingInterfaceUsingGlobalArray();
}
}
}();// invoke the function
It's like reviving this post from the dead, but I had the same problem today, jQuery version greater than 1.6 has this ability:
https://api.jquery.com/jquery.holdready/
And I've used it like this:
$.holdReady(true);
var remoteJSONContent = null;
$.getJSON("http://www.example.com/remote.json", function(data) {
remoteJSONContent = data;
$.holdReady(false);
});
$(document).ready(function(){
console.log(remoteJSONContent);
});
Without using holdReady, I was getting null, after, I got the content.
For anyone still searching the answer for this.
I have the following code which is included in a keypress function:
$.getJSON('dimensions.json', function(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
});
I'm trying to first get the JSON string, save it in a variable and then run the each(). I want to basically separate the each() to be unlinked to the getJSON() function because I don't want it to fetch the json file for every keypress.
I've tried this, but it didn't work:
var JSONstr = $.getJSON('dimensions.json');
$.each(JSONstr, function(index) {
$('#div1').append(index);
});
In your first example, you do $.each in the callback. The callback is executed by some other callback after there result is received, while $.getJSON returns immediately without waiting for the result (since there is no blocking in JavaScript by design).
Therefore the code in your second example can never work: the $.each begins before any result is received from the web server, probably even before the request is sent. Whatever the return value of $.getJSON is, it can't, by the design of JavaScript, be the result of AJAX request.
UPD: Saw your comment, now I understand what you wanted to do. Here's a simple example of how to do this:
function ActualHandler(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
}
function KeypressHandler() {
if (window.my_data) { // If we have the data saved, work with it
ActualHandler(window.my_data);
}
else { // Otherwise, send the request, wait for the answer, then do something
$.getJSON('dimensions.json', function(data) {
window.my_data = data; // Save the data
ActualHandler(data); // And *then* work on it
});
}
}
Here, the ActualHandler is not launched before the data is received, and once that happens, all subsequent clicks will be handled immediately.
The downside in this particular case is that if user clicks again while the first request is running, one more will be sent. But to fix that you would need to maintain some queue, which is kind of out of scope here.
You fell into the asynchronous trap. Your $.each() function doesn't wait for your $.getJSON() call to get the data. You can get around this by using the good 'ol $.ajax() function. Like this:
function processJSON(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
}
$.ajax({
url: 'dimensions.json',
dataType: 'json',
async: false,
success: processJSON(data)
});