I have an Ajax call that is called once and then it calls itself recursively in order to manage a newsletter send job (the send is managed by the send.php script). The call works pretty well (generally for the first 15-20 mins it goes well), the only problem is that sometime the call never returns but it does not trigger the error function that you can see inside the ajax call. Infact the alert is never called and the "SEND ERROR!!" message is never displayed. What can be the problem?
The following is the interested function:
function _ajax_send(id_send, curr_index)
{
$.ajax({
type: "POST",
url: "ajax/send.php",
data: { id: id_send, index: curr_index },
async: true,
dataType: "json",
global: true,
timeout: 130000,
erorr: function(xhr, status, error) {
alert("SEND ERROR!!");
setTimeout(function(){ _ajax_send(<?php echo $_GET['id']; ?>, Number(sent)); }, 3000);
},
success: function(data) {
if(data.result) {
if(!data.completed)
{
calls = calls + 1;
_ajax_send(id_send, data.curr_index);
}
else
{
done = true;
}
}
else
{
alert("Logic Error. Cause: " + data.error);
}
}
});
}
Thank you very much for any help ;)
Related
I have tried ways to search for a solution but I can't seem to find the right combination of words or something... here goes:
I have an ASP.NET MVC application that users scan inventory/package barcodes into. Every time someone scans an item, I make an async request and then display a popup message with information about the package. This part works as expected and does not block the application during the request:
$.ajax({
type: 'GET',
dataType: 'json',
async: false,
url: '#Url.Action("SingleOrderLookup")?trackingNumber=' + trackingId,
success: function (result) {
if (result.success) {
var audio = findAudio(result.model, audioClips, saturdayAudio);
suppressDefaultSound = true;
var titleText = result.model.displayPromptText;
if (result.model.isRefrigerated) {
isRefrigerated = true;
titleText = "<p style='color: blue;'>(REFRIGERATED)</p>" + "<p>" + result.model.displayPromptText + "</p>";
}
swal.fire({
title: titleText,
text: "Place in route for " + result.model.displayPromptText,
type: "success",
showCancelButton: false,
confirmButtonText: "Sorted",
cancelButtonText: "Cancel",
timer: 1750,
preConfirm: function () {
return new Promise(function (resolve) {
resolve();
}, 1000);
}
}).then(result => {
if (result.value) {
}
});
var dupe = findOrderByTrackingNumber(trkNumbers, result.model.trackingId);
if (!dupe) {
trkNumbers.push({ trackingNumber: trackingId, depotId: result.model.destinationHub });
pkgCount++;
if ($("#divUpdatePickup").is(":hidden"))
$("#divUpdatePickup").show();
AddLogToTable(trackingId);
} else {
//audible feedback that duplicate was scanned
//if (!trkBin) PlayAudio(2);
//PlayAudio(2);
}
//playing audio
if (isRefrigerated) {
setTimeout(function () {
if (audio) playByteArray(audio);
}, 1500);
PlayRefrigerate();
} else {
if (audio) playByteArray(audio);
}
}
if (result.nullRoute) {
addToTrkNumbers = false;
Swal.fire({
title: "NO ROUTE DEFINED",
text: "Unable to match order to a route!",
type: "warning",
showCancelButton: false
});
}
}
});
However, I want the page to make another async call to populate a variable with an array of objects, transparently and without blocking the user from making scans and receiving information back from the async calls from the above code. This call should occur immediately when the page is loaded, and it could take more than a minute or two to receive all the data expected from this call. Once the response is back, the collection variable (zipSort[]) should be populated. The data in this variable will contain a "cache" of elements that the page can query against to avoid having to make individual server-side calls after each scan (in essence, I want to "front-load" data needed for the scan events and once completed, individual calls to the server should not be necessary since this variable should contain 99% of the IDs expected to be scanned).
This is where I'm having an issue and it's probably due to a lack of understanding of how async calls/JS promises work. Here is the code I have so far for this:
//array to hold data on expected tracking number scans
var zipSort = []
async function getCheckinGroup(zipSort) {
console.log("Fetching complete check-in group...");
var url = '/SortFacility/HubManager/GetOrders';
var promise = new Promise((resolve,reject) => {
$.ajax({
type: "GET",
url: url,
cache: false,
async: true,
contentType: "application/json",
success: function (result) {
if (result.success) {
console.log("Retrieval success");
try {
zipSort = result.model;
resolve(result.model);
} catch (ex) {
reject("Some error?");
}
} else {
reject("Some error?");
}
},
error: function (ob, errStr) {
reject("Something went wrong");
}
});
});
return promise;
}
//don't want this to hold up execution of the rest of the code, so zipSort[] should
//remain empty and get set transparently when the ajax response is returned:
getCheckinGroup(zipSort);
Every version of code I'm trying out from articles and tutorials I have read holds up the UI and keeps users from being able to scan items while the response hasn't been returned. What am I missing? How should I change this so that (a) users can begin scanning immediately once the page has loaded and receive information from individual async calls to the DB, and (b) zipSort[] can be populated with the totality of any data potentially needed for these scans, and once populated, scan events trigger a lookup on that variable instead of continued individual calls to the database?
Any help would be appreciated!
Edit: tried simply adding this call in-line and no matter where I put it, it blocks the other code from running until response is received, even though async is set to true:
$.ajax({
type: "GET",
url: url,
cache: false,
async: true,
contentType: "application/json",
success: function (result) {
console.log("Data received.");
zipSort = result.model;
}
});
Thanks everyone for your help. I found this little gem, which solved my problem:
https://josef.codes/c-sharp-mvc-concurrent-ajax-calls-blocks-server/
Applying [SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)] to my controller class enabled concurrent async ajax calls.
In my dashboard.php I have a Javascript function that is called based on the user clicking a button. When the button is clicked, it calls a JavaScript function called getTeamMembers and values are passed across to it. The values passed across to this function are then sent to a PHP function (which is also located in dashboard.php).
However I am not getting any success and was hoping that someone could guide me on where I am going wrong. I am a noob when it comes to AJAX so I assume I am making a silly mistake.
I know my function is definitely getting the intended variable data passed to it, after doing a quick window.alert(myVar); within the function.
This is what I have so far:
function getTeamMembers(teamID,lecturer_id) {
var functionName = 'loadTeamMembersChart';
jQuery.ajax({
type: "POST",
url: 'dashboard.php',
dataType: 'json',
data: { functionName: 'loadTeamMembersChart', teamID: teamID, lecturer_id: lecturer_id },
success: function(){
alert("OK");
},
fail: function(error) {
console.log(error);
},
always: function(response) {
console.log(response);
}
}
);
}
Before calling the desired php function, I collect the sent varaibles just before my php Dashboard class starts at the top of the file. I plan to pass the variables across once I can be sure that they are actually there.
However, when I click the button, nothing can be echo'd from the sent data.
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
if (!empty($_POST["teamID"]) && !empty($_POST["lecturer_id"]))
{
$teamID = $_POST['teamID'];
$lecturer_id = $_POST['lecturer_id'];
echo $teamID;
echo " is your teamID";
}
else
{
echo "no teamID supplied";
}
}
you else statement in you success function , and that's not how you set fail callback, try the following and tell us what do you see in the console.
function getTeamMembers(teamID,lecturer_id) {
jQuery.ajax({
type: "POST",
url: 'dashboard.php',
dataType: 'json',
data: {functionname: 'loadTeamMembersChart', arguments: [teamID, lecturer_id]},
success: function(data) {
console.log(data);
},
fail: function(error) {
console.log(error);
},
always: function(response) {
console.log(response);
}
});
}
Seems like your function is not returning a success message when getting into the following statement.
if ($result) {
"Awesome, it worked"
}
Please try to add a return before the string.
if ($result) {
return "Awesome, it worked";
}
It can be other factors, but the information you provided is not enough to make any further analysis.
When first opening the mobile app homepage it returns an error
"TypeError: Jqueryxxxxxx is not a function" although it shows the API
callback results
"jQuery111309512500500950475_1459208158307({"code":1,"msg":"Ok","details":{"data"..."
according to Firebug.
I have to open different app pages then return to homepage to see Featured Merchants parsed.
JS Code
case "page-home":
callAjax('getFeaturedMerchant','');
break;
case "getFeaturedMerchant":
displayFeaturedRestaurant( data.details.data ,'list-featured');
break;
case "getFeaturedMerchant":
createElement('list-featured','');
break;
API PHP Code
public function actiongetFeaturedMerchant()
{
$DbExt=new DbExt;
$DbExt->qry("SET SQL_BIG_SELECTS=1");
$start=0;
$limit=200;
$and='';
if (isset($this->data['restaurant_name'])){
$and=" AND restaurant_name LIKE '".$this->data['restaurant_name']."%'";
}
$stmt="SELECT a.*,
(
select option_value
from
{{option}}
WHERE
merchant_id=a.merchant_id
and
option_name='merchant_photo'
) as merchant_logo
FROM
{{view_merchant}} a
WHERE is_featured='2'
AND is_ready ='2'
AND status in ('active')
$and
ORDER BY sort_featured ASC
LIMIT $start,$limit
";
if (isset($_GET['debug'])){
dump($stmt);
}
if ($res=$DbExt->rst($stmt)){
$data='';
foreach ($res as $val) {
$data[]=array(
'merchant_id'=>$val['merchant_id'],
'restaurant_name'=>$val['restaurant_name'],
'logo'=>AddonMobileApp::getMerchantLogo($val['merchant_id']),
);
}
$this->details=array(
'data'=>$data
);
$this->code=1;$this->msg="Ok";
$this->output();
} else $this->msg=$this->t("No Featured Restaurant found");
$this->output();
}
I'm stuck and confused what's causing this error and how to resolve it.
EDIT: Added the full callAjax Function
function callAjax(action,params)
{
/*add language use parameters*/
params+="&lang_id="+getStorage("default_lang");
dump(ajax_url+"/"+action+"?"+params);
ajax_request = $.ajax({
url: ajax_url+"/"+action,
data: params,
type: 'post',
async: false,
dataType: 'jsonp',
timeout: 6000,
crossDomain: true,
beforeSend: function() {
if(ajax_request != null) {
/*abort ajax*/
hideAllModal();
ajax_request.abort();
} else {
},
complete: function(data) {
ajax_request=null;
hideAllModal();
},
success: function (data) {
dump(data);
if (data.code==1){
switch (action)
{
case "getFeaturedMerchant":
displayFeaturedRestaurant( data.details.data ,'list-featured');
//$(".result-msg").text(data.details.total+" Restaurant found");
$(".result-msg").text(data.details.total+" "+ getTrans("Featured Restaurants found",'restaurant_found') );
break
)
else {
/*failed condition*/
switch(action)
{
case "getFeaturedMerchant":
createElement('list-featured','');
//$(".result-msg").text(data.msg);
break;
}
},
error: function (request,error) {
hideAllModal();
if ( action=="getLanguageSettings" || action=="registerMobile"){
} else {
onsenAlert( getTrans("Network error has occurred please try again!",'network_error') );
}
}
}};
Calling URL is:
http://domain.com/mobileapp/api/getFeaturedMerchant?
This is actually an issue with the way jQuery handles the abort method when using JSONP, which I have encountered before.
Basically, JSONP works by adding a script tag to the DOM, and adding a callback it will fire when it executes.
Unlike AJAX, the request generated by a script tag cannot be cancelled, so when you call abort like below, it only sort-of works.
ajax_request.abort();
jQuery will unset the global callback it registered, jQuery111309512500500950475_1459208158307 in your case, but it cannot stop the script from trying to run it when it loads. Thus, when it tries to call the now-undefined function, you get the error.
Personally, I think jQuery should set, or have an option to set, these global handlers to an empty function or something instead, but it doesn't. In your case, if possible, I would recommend avoiding making the request if you only plan to abort it before sending it.
Edit:
Two issues I see:
Your code bracing is wrong leading to some unintended execution paths.
You are trying to call .abort() on a JSONP request which is not supported. Doing so will cause the callback function to be removed BEFORE the JSONP script loads that tries to call that callback function. The .abort() will stop the processing of the request, but leave you with the type of script error you see reported.
Here are the notes on the code bracing:
It appears like your code bracing is wrong so you are executing the success callback too soon. When I put your callAjax through a code formatter, it looks like this (see the spot marked "problem area"
function callAjax(action, params) {
/*add language use parameters*/
params += "&lang_id=" + getStorage("default_lang");
dump(ajax_url + "/" + action + "?" + params);
ajax_request = $.ajax({
url: ajax_url + "/" + action,
data: params,
type: 'post',
async: false,
dataType: 'jsonp',
timeout: 6000,
crossDomain: true,
beforeSend: function () {
if (ajax_request != null) {
/*abort ajax*/
hideAllModal();
ajax_request.abort();
} else {}, // <========== problem here
complete: function (data) {
ajax_request = null;
hideAllModal();
},
success: function (data) {
dump(data);
if (data.code == 1) {
switch (action) {
case "getFeaturedMerchant":
displayFeaturedRestaurant(data.details.data, 'list-featured');
//$(".result-msg").text(data.details.total+" Restaurant found");
$(".result-msg").text(data.details.total + " " + getTrans("Featured Restaurants found", 'restaurant_found'));
break
) // <========== problem starts here
else {
/*failed condition*/
switch (action) {
case "getFeaturedMerchant":
createElement('list-featured', '');
//$(".result-msg").text(data.msg);
break;
}
},
error: function (request, error) {
hideAllModal();
if (action == "getLanguageSettings" || action == "registerMobile") {} else {
onsenAlert(getTrans("Network error has occurred please try again!", 'network_error'));
}
}
}
};
Add a missing brace in the problem area and you get this. But this is still not really correct. The two switch statements in the success handler are not correct syntax so they need to be fixed too. I think your issue is that you had some counteracting syntax errors that allowed the code to somehow run, but not execute in the proper way.
function callAjax(action, params) {
/*add language use parameters*/
params += "&lang_id=" + getStorage("default_lang");
dump(ajax_url + "/" + action + "?" + params);
ajax_request = $.ajax({
url: ajax_url + "/" + action,
data: params,
type: 'post',
async: false,
dataType: 'jsonp',
timeout: 6000,
crossDomain: true,
beforeSend: function () {
if (ajax_request != null) {
/*abort ajax*/
hideAllModal();
ajax_request.abort();
}
}, // <======== Added this brace to close off the function
complete: function (data) {
ajax_request = null;
hideAllModal();
},
success: function (data) {
dump(data);
if (data.code == 1) {
switch (action) {
case "getFeaturedMerchant":
displayFeaturedRestaurant(data.details.data, 'list-featured');
//$(".result-msg").text(data.details.total+" Restaurant found");
$(".result-msg").text(data.details.total + " " + getTrans("Featured Restaurants found", 'restaurant_found'));
break
) // <============= This is out of place and so are the next few lines
else {
/*failed condition*/
switch (action) {
case "getFeaturedMerchant":
createElement('list-featured', '');
//$(".result-msg").text(data.msg);
break;
}
},
error: function (request, error) {
hideAllModal();
if (action == "getLanguageSettings" || action == "registerMobile") {} else {
onsenAlert(getTrans("Network error has occurred please try again!", 'network_error'));
}
}
}
}
});
}
One possible way to approach fixing this is to fix the missing brace in the beforeSend: handler, then remove most of the success handler code to this stub and then add back in the proper code in the success handler under a careful eye:
function callAjax(action, params) {
/*add language use parameters*/
params += "&lang_id=" + getStorage("default_lang");
dump(ajax_url + "/" + action + "?" + params);
ajax_request = $.ajax({
url: ajax_url + "/" + action,
data: params,
type: 'post',
async: false,
dataType: 'jsonp',
timeout: 6000,
crossDomain: true,
beforeSend: function () {
if (ajax_request !== null) {
/*abort ajax*/
hideAllModal();
ajax_request.abort();
}
}, // <======== Added this brace to close off the function
complete: function (data) {
ajax_request = null;
hideAllModal();
},
success: function (data) {
dump(data);
if (data.code == 1) {
// <=========== Removed faulty code in here
}
}
});
}
Original Answer
That particular error and network response looks like your client wants some data from the server. The client (for some reason) decides that it needs to use JSONP to get the response from the server so the server is sending back JSONP, but the client code that sent the request did not properly prepare for the JSONP request by defining the appropriate callback function that the JSONP script can call.
You will either have to switch to a regular Ajax call that is not JSONP or we will have to see the details of your callAjax() implementation to see why the JSONP response is not working.
I am trying to use Ajax to reload data from a database. However, the Ajax doesn't call the controller action that I specified in the url:. Here is my Ajax code:
function selectFieldChanged(id){
$.ajax({
type: "POST",
url: Routing.generate('demo_ajax'),
data: id,
success: function(){
alert("Success");
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert('Error : ' + errorThrown);
}
});
}
$(document).ready(function(){
var id = $(this).val();
$('#form_patient').change(function(){selectFieldChanged(id)});
});
The routing.xml :
demo_ajax:
pattern: /ajax/patient
defaults: { _controller: DemoBundle:Default:index}
options:
expose: true
So, I tried to simply echo the value out in the indexAction to see whether it is called or not.
public function indexAction(Request $request)
{
if($request->isXmlHttpRequest()){
echo "xmlHttpRequest is called";
}
if($request->getMethod()=='POST'){
echo 'POST is called';
}
}
However, I didn't get anything from the indexAction but I got the alert message, `Success, from my Ajax What did I do wrong?
The success callback receives data from your server so a variable must be declared to capture it:
success: function(data){ // <-----
console.log(data);
alert("Success");
},
Hello i'm using an ajax script redirecting to a php page where i make the validation. After there are no validation errors i want to redirect to another page but i cant manage to make it work. here is my script:
<script type="text/javascript" src="js/jquery.form.js"></script>
<script type="text/javascript" >
$(document).ready(function() {
$("#imageform").ajaxForm({
target: \'#preview \',
});
});
</script>
and here is the external php were i make the validation
<?php
require_once('../core/dbconfig.php');
mysql_query("SET NAMES utf8");
$fname=$_POST['name'];
$email=$_POST['email'];
$country=$_POST['country'];
$city=$_POST['city'];
$type=$_POST['type'];
$story=$_POST['story'];
$cookie=$_COOKIE['cookie'];
$sizee = $_FILES['img1']['size'];
if (!$fname or !$city or !$email or !$country or (!$story && $sizee==0))
{
if ($sizee==0 && !$story)
{
echo'<p style="color:red;">Please upload a photo or type your story.<p>';
}
if(!$fname)
{
echo'<p style="color:red;">Please enter your name.<p>';
}
$regex = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/';
if (preg_match($regex, $email)) {
}
else
{
echo'<p style="color:red">Please enter a valid email.<p>';
}
if(!$country)
{
echo'<p style="color:red">Please select your country.<p>';
}
if(!$city)
{
echo'<p style="color:red">Please enter your city.<p>';
}
}
else
{
....
}
what i want to achiev is that after all the conditions are completed to redirect to a confirmation page. If i use a succes:window.location.href = "example.php" doesnt work as intended.
Thnx in advance.
$(myform).ajaxForm({
beforeSend: function() {
},
error: function() {
},
complete: function(response) {
window.location.href='yourfile.php'
}
});
With ajaxForm you'r can use function complete, according to documentation this function... "A function to be called when the request finishes (after success and error callbacks are executed)".
But you need consider property async, By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false.
$(myform).ajaxForm({
async: true,
error: function(response) {
//something is wrong
},
complete: function(response) {
window.location.href='yourfile.php'
}
});
OR
$(myform).ajaxForm({
async: false,
error: function(response) {
//something is wrong
},
complete: function(response) {
window.location.href='yourfile.php'
}
});
$.ajax({
type: "POST",
dataType: "json",
url: "friends/get_user_friends",
data:{
action:"action",
type:"type"
},
success: function (response) {
window.location.href = "http://google.com";
},
error: function (response, ajaxOptions, thrownError) {
}
});