jquery form send ajax [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
i have the following validate script to run before the form is submitted:
function validateMyForm(){
var numberTo = $('.to').length
$('.to').each(function(){
var product_id = $(this).closest('tr').find('input').get(0).id;
var todate = $(this).val();
var from = $(this).prev().prev().val();
$.ajax({
type: 'POST',
url: myBaseUrl + 'Products/ajax_change_date',
dataType: 'json',
data: {
id: product_id,
todate: todate,
from: from
},
success: function (data) {
numberTo--;
}
});
});
while(numberTo != 0){
}
return true;
}
However when i run this i get a message box in firefox saying its waiting for the script to complete.
How do i avoid that while still keeping the ajax?

Using:
while(numberTo != 0){
}
You create infinity loop and your scrip stop executing. This is why you get this error on Firefox.
You will need to have callback to check numberTo variable.
For example:
function validateMyForm(){
var numberTo = $('.to').length;
function checkNumberTo() {
if( numberTo === 0 ) {
alert( 'AJAX Completed' );
// here you should include your code to manually submit the form
}
}
$('.to').each(function(){
var product_id = $(this).closest('tr').find('input').get(0).id;
var todate = $(this).val();
var from = $(this).prev().prev().val();
$.ajax({
type: 'POST',
url: myBaseUrl + 'Products/ajax_change_date',
dataType: 'json',
data: {
id: product_id,
todate: todate,
from: from
},
success: function (data) {
numberTo--;
checkNumberTo()
}
});
});
return false;
}

If you want a more elegant solution you might want to try a promise library.
Here is an essay https://gist.github.com/domenic/3889970 that presents the downside of using callbacks and the solution to it - Promises. The essay is long, but it is worthy to read.
To get to how this new concept applies to you, you should try researching Promise composition, here is the first article I could find on Google on this:
http://strongloop.com/strongblog/how-to-compose-node-js-promises-with-q/.
var x = 10; var promise1 = Q($.ajax(...)).then(function () {
x = 20; });
var promise2 = Q($.ajax(...)) .then(function () {
x = 30; });
var groupPromise = Q.all([ promise1(), promise2() ])
groupPromise.then(function (results) { }, console.error) // Kris Kowal's example
Promises l and 2 execute in paralel and one does not know which will be fulfilled first.
Here are 2 relevant promise libraries:
https://github.com/kriskowal/q
https://github.com/cujojs/when

Related

loop chained async ajax calls with promise and returns between functions

I am loading results in batches and looking for a solution that will prevent the screen from freezing until all my ajax calls have returned. Someone recommended using async promises (is that the correct solution?) but I don't understand how the syntax works to pass parameters between the chained calls.
It's the equivalent of this looped chain of many ajax calls except I need all calls to depend on the result from the previous call (in this example the loops for url1 all fire simultaneously which is not what I want). The run should end when the returned boolean "proceed" (from any of the ajax calls) is false, not when the last loop and url have been reached.
for (let i = 0; i < numLoops; i++) {
$.ajax({
url: url1,
type: "POST",
data : jQuery.param({loop: i}),
success: function(response) {
var result = JSON.parse(response);
if(result['proceed']){
$.ajax({
url: url2,
success: function(response) {
var result = JSON.parse(response);
$( "#load" ).html(result['results']);
if(result['proceed']){ ... and so on
I am trying to use jquery .when .then promises with these functions:
function First(loop, proceed, updated){
if(proceed)
{
$.ajax({
url: url1,
type: "POST",
data : jQuery.param({loop: loop}),
success: function(response) {
var result = JSON.parse(response);
$( "#load" ).html(result['results']);
updated(result['proceed']);
}
});
}
}
function Second(proceed, updated){
if(proceed)
{
$.ajax({
url: url2,
success: function(response) {
var result = JSON.parse(response);
$( "#load" ).html(result['results']);
updated(result['proceed']);
}
});
}
}
function Third(proceed, updated){
if(proceed)
{
$.ajax({
url: url3,
success: function(response) {
var result = JSON.parse(response);
$( "#load" ).html(result['results']);
updated(result['proceed']);
}
});
}
}
I'm having a hard time figuring out how to chain them so that the return from previous function is passed to the next function.
This incorrect syntax describes what I'm trying to do:
var proceed=true;
for (let i = 0; i < numLoops; i++) {
$.when(First(i, proceed, updated); function updated(content) {var proceed=contents;} )
.then(Second(proceed, updated); function updated(content) {var proceed=contents;})
.then(Third(proceed, updated); function updated(content) {var proceed=contents;})
}
How to pass updated proceed from First to Second?
How to pass updated proceed from Third to First at end of each loop?
I'm not super versed with javacript and would be most grateful for pointers. Thanks!
First, convert the $.ajax calls into real Promise objects, as described in this thread:
function asyncAjax(options){
return new Promise(function(resolve, reject) {
options.success = resolve;
options.error = reject;
$.ajax(options);
});
}
Alternatively, use the Fetch API, which supports promises by default.
Then use an async function to make the requests:
for (let i = 0; i < numLoops; i++) {
let response = await asyncAjax({
url: url1,
type: "POST",
data: jQuery.param({loop: i})
});
let result = JSON.parse(response);
if (result['proceed']) {
response = await asyncAjax({ url: url2 });
result = JSON.parse(response);
...
}
}

JS Function including AJAX returning undefined [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
function idToUnitNum(id){
$.ajax({
type: "POST",
url: "ajax_officerFromId.php",
data: {'id': id},
success: function(dataString) {
ofd = JSON.parse(dataString);
var result = ofd.data;
console.log(result);
return result;
}
});
}
This is the function. It's called from another function. I tried testing it's output by logging result before it returns, and it displays the appropriate result.
Result (JSON):
{"success":"true","time":1524462577,"data":"ADMIN"}
However, when I try catching the variable (a string), it does shows as "undefined".
It's probably a stupid mistake.
Calling the function:
var unitnum = idToUnitNum(adata.arresting_officer);
console.log(unitnum);
Thank you for your assistance!
pass callback function to idToUnitNum. something like below
function idToUnitNum(id,callback){
$.ajax({
type: "POST",
url: "ajax_officerFromId.php",
data: {'id': id},
success: function(dataString) {
ofd = JSON.parse(dataString);
var result = ofd.data;
console.log(result);
callback(result);
}
});
}
Hi Please change the AJAX function like this :
function idToUnitNum(id){
var dfd = $.Deferred();
$.ajax({
type: "POST",
url: "ajax_officerFromId.php",
data: {'id': id},
success: function(dataString) {
ofd = JSON.parse(dataString);
var result = ofd.data;
dfd.resolve(result);
// return result;
}
});
return dfd.promise();
}
And you can use this function like this
idToUnitNum(adata.arresting_officer).done(function(response){
console.log(response);
});
FYI : not tested code
function idToUnitNum(id){
var result = '';
$.ajax({
type: "POST",
url: "ajax_officerFromId.php",
async: false,
data: {'id': id},
success: function(dataString) {
ofd = JSON.parse(dataString);
result = ofd.data;
}
});
return result;
}
Thank you to whoever suggested I turn off async and call it outside fo the AJAX request. Solved the issue.
You should either use a callback function as a parameter or, even better, use promises. Simply put return in front of your ajax call and call .then() on the return value to read the result when it is available.
This has been asked many times, so you shouldn’t have any trouble finding more information about these solutions

Perform action at end of for loop javascript [duplicate]

This question already has answers here:
Wait until all jQuery Ajax requests are done?
(22 answers)
Closed 5 years ago.
I have been trying to redirect a page after the for loop has finished but it executes it before the for loop even if the code is outside the for loop. So am wondering if there is some way of executing code and redirecting to another page after the for loop is done in JavaScript. This is my code.
$('#submit').click(function(e) {
e.preventDefault();
var total = $('#total').val();
for (var i = 0; i < total; i++) {
if ($('#check_' + i).is(':checked')) {
// The string to be posted to the submit file
var dataString = 'month=' + month + '&year=' + year + '&patient_id=' + patient_id;
// AJAX code to submit form.
$.ajax({
type: "POST",
url: "pages/views/payroll/bulk_payroll_functions.php",
data: dataString,
cache: false,
success: function(result) {
alert("good");
}
});
}
}
alert("All members payrolls made");
window.location = ("index.php?lang=en&page=view_payroll");
})
The code is working as you're expecting - the AJAX requests are being made. However, because they are asynchronous, you are not guaranteed that they'll have finished before you redirect.
The cleanest way to do this would be to use the Promises which $.ajax returns.
You can then use $.when to redirect when all ajax requests are completed:
$('#submit').click( function(e) {
e.preventDefault();
// array to store the promises
var promises = [];
var total = $('#total').val();
for(var i = 0; i < total; i++){
if($('#check_' + i).is(':checked')){
// The string to be posted to the submit file
var dataString = 'month=' + month + '&year=' + year + '&patient_id=' + patient_id ;
// AJAX code to submit form.
promise = $.ajax({
type: "POST",
url: "pages/views/payroll/bulk_payroll_functions.php",
data: dataString,
cache: false,
success: function (result) {
alert("good");
}
});
// add ajax request to the promises
promises.push(promise);
}
}
// redirect when all promises have resolved
$.when(promises).then(function () {
alert("All members payrolls made");
window.location = ("index.php?lang=en&page=view_payroll");
});
});

Issue accessing variable outside of function scope [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I'm pulling data from an XML feed. That is all working correctly but I need productIDs available outside the function.
// Get feed data
$.get('example-feed.xml', function (data) {
var $xml = $(data);
// Collect array of product IDs
var productIDs = [];
// extract ids from xml
$xml.find("item").each(function() {
var $this = $(this)
item = {
id: $this.find("id").text()
}
// get the id
var itemID = item.id;
// push ids to array
productIDs.push(itemID);
});
console.log(productIDs); // Works as expected
});
console.log(productIDs); // Undefined, also as expected
How can I adjust my function to work like that?
example = function(){
var productIDs = "my content ids"
return {'productIDs': productIDs}
}
var retrive = example();
console.log(retrive.productIDs);
There are multiple ways you can do this, but the best thing here is to use promises, because JQuery's get is usually asynchronous function and you have to wait for it's completion to get product ids
You may do it like this
function fetchThings () {
return new Promise(function (yes, no) {
$.get('example-feed.xml', function (data) {
// some code here
console.log(productIDs); // Works as expected
yes(productIDs);
});
});
}
fetchThings().then(function (productIDs) {
// do stuff with prodcut ids here
});
The other way to do it would be making your $.get call synchronous, so replace it by
var productIDs;
$.ajax({url: 'example-feed.xml', type: "GET", async: false, success: function (data) {
// process productIDs here
}});
// use productIDs here
Update:
Here is a snippet of async ajax, click run to check
var postIDs;
$.ajax({
url: 'http://jsonplaceholder.typicode.com/posts',
method: 'GET',
async: false,
success: function(posts) {
postIDs = posts.map(function (p) { return p.id; });
}
});
document.write(JSON.stringify(postIDs));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Looping through array with callback

I am trying to run through a array send to a php file and on a callback send the next value after the php has completed its download. Here what i have so far.
my array come through as follows.
["http://example.com/test1.zip", "http://example.com/test2.zip", "http://example.com/test3.zip", "http://example.com/test4.zip", "http://example.com/test5.zip"]
above is the output from console.log(values); below. it grabs some urls from checkbox values.
$('.geturls').live('click',function(){
var values = new Array();
$.each($("input[name='downloadQue[]']:checked"), function() {
values.push($(this).val());
ajaxRequest($(this).val(),function(response){
console.log(response);
});
});
console.log(values);
return false;
});
this then calls a ajax function which i am trying to do a callback on.
function ajaxRequest(urlSend,callback){
var send = {
url: urlSend
}
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
//dataType: "json",
//timeout: 8000,
beforeSend: function() {
},
success: function(response) {
callback('added');
},
error: function (response) {
callback('false');
}
});
}
this will then send to a php file.
function upload(){
$output = shell_exec("wget {$_POST['url']} 2>&1");
return true;
}
What i am trying to do is after the callback from one url which it has download fully then grab the next value from the array and download that url and so on until all the urls in the array are downloaded fully.
at the moment it just downloads the first value and then crashes because it doesn't restart the loop after a return value of true is returned.
Hope this makes sense to someone just looking for some help on the best way to loop through an array of values with a callback after complete.
May be this structure can help you. In this variant you go next URL only after successful completion of the previous Ajax call.
var arr = ['url0','url1','url2','url3'];
var index = 0;
function Run(){
DoAjax(arr[index]);
}
function Next( ){
if(arr.count = index-1)
{
index =0;
return;
}else{
DoAjax(arr[index ]);
}
}
function DoAjax(url){
$.ajax({
type: "POST",
url: url,
data: send,
beforeSend: function() {
},
success: function(response) {
index ++;
Next();
// Addition logic if needed
},
error: function (response) {
}
});
}
Run()
Now that I have a bit more time, I thought it would be good to show an alternative which takes advantage of the fact that jquery ajax is now implemented as a deferred. Meaning you can use pipe chaining to do all the work for you. I've also eliminated the callbacks by taking advantage of the deferred behavior.
This should give you the idea.
// Use jquery deferred pipe chaining to force
// async functions to run sequentially
var dfd = $.Deferred(),
dfdNext = dfd,
x,
values = [],
// The important thing to understand here is that
// you are returning the value of $.ajax to the caller.
// The caller will then get the promise from the deferred.
ajaxRequest = function (urlSend) {
var send = {
url: urlSend
}
return $.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
});
};
// Starts things running. You should be able to put this anywhere
// in the script, including at the end and the code will work the same.
dfd.resolve();
// Deferred pipe chaining. This is the main part of the logic.
// What you want to note here is that a new ajax call will
// not start until the previous
// ajax call is completely finished.
// Also note that we've moved the code that would
// normally be in the callback.
// Finally notice how we are chaining the pipes by
// replacing dfdNext with the return value from the
// current pipe.
for (x = 1; x <= 4; x++) {
values.push(x);
dfdNext = dfdNext.pipe(function () {
var value = values.shift();
return requestAjax(value).
done(function(response) {
// Code here that you would have
// put in your callback.
console.log(response);
}).
fail(function(response) {
console.log(response);
};
});
}
Working example you can play with on jsFiddle.

Categories

Resources