I have the following Ajax call:
$.ajax({
type: 'POST',
url: myBaseUrl + 'Products/addItemToBasket',
dataType: 'json',
data: {
id: window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1),
amount: amount
},
success: function (data) {
alert(data);
var dat = JSON.parse(data);
}
}
});
Now this calls the following method in php:
public function addItemToBasket()
{
if ($this->request->is('post')) {
//todo delete efter at have insat fancybox med valg af antal styk. (sendes via ajax).
$shopping = null;
$item = $this->Product->find('first',array('conditions' => array('Product.id' =>$this->request->data['id'])));
if(isset($_SESSION['basket'])){
$shopping = $_SESSION['basket'];
}else{
$shopping = array();
}
array_push($shopping,$item);
$_SESSION['basket'] = $shopping;
echo json_encode($_SESSION['basket']);
}
}
When i try to debug it everything is working (it gets into the php function) and updates my $_SESSION variable.
BUT it never runs the success function and it never alerts the data.
What am i doing wrong?
NOTE: I know this question is from a couple of months ago, but any help will be useful for people looking for answers to this kind of problems.
As far as I know, because I'm running with a similar problem, it all depends on the response you get from the webservice (you can check it out with Chrome debugging console). For instance, I'm getting this now:
readyState: 4
statusText: "OK"
responseText: (The result I am looking for)
The problem is, as you say, I always get to run the Error part of the callback, never the Success, even if I'm getting the right responseText. As I've read, that's because the call to the WS was OK, but the parsing from JSON wasn't, so it calls "error".
So far I don't know how to fix it, but maybe this will give a clue.
Related
I am new to php and javascript. I am trying to post some variables to another php file using ajax. From my main php file, I have a javascript setInterval calling a function to send data every 500ms. The function called is:
function UpdateDB(xval, yval) {
TimeCount++;
// console.log(xval, yval, TimeCount);
$.ajax({
type: "POST",
url: "ud.php",
data: { x: xval.toString(), y: yval.toString(), t: TimeCount.toString() }
});
return TimeCount;
}
This function runs fine as I get the console log data (if I uncomment). I can also see in developer tools (chrome) in the network, the file ud.php appears to be run, but I do not believe this is the case. ud.php is a simple file that updates data in a table:
//<script type="text/javascript">console.log("ud");</script>
<?php
if (!isset($_SESSION['id'])) {
exit();
}
//require "includes/dbh.inc.php";
$sql = "UPDATE units SET JoyX='$x', SET JoyY='$y', SET JoyTimeStamp='$t', WHERE SN='$serial'";
//$sql = "UPDATE units SET JoyTimeStamp='$t' WHERE SeralNumber='$serial'";
mysqli_query($conn, $sql);
mysqli_close($conn);
exit();
?>
I wrote the commented out line at the top to see if the file was run, but when uncommented it does not log to the console.
I suspect my ajax query is incorrectly formatted, but again I am new to this and have searched for the last few days to find an answer without success.
Thanks for any help.
The PHP file is successfully being invoked, you just have an invalid expectation of the result. Check the network tab in your browser's debugging tools. Are there any error codes in the request/response? Does the response contain the information you expect? If so then it's working.
The question is... What are you doing with that response?
The AJAX operation by itself doesn't do anything with the response. But it gives you an opportunity to do something with it. For example, in the jQuery .ajax() call you're using, there's a success callback which gets invoked on a successful result. So you can do something like this:
$.ajax({
type: "POST",
url: "ud.php",
data: { x: xval.toString(), y: yval.toString(), t: TimeCount.toString() },
success: function () {
console.log("ud");
}
});
So instead of trying to return new JavaScript from the server, you write the JavaScript here that you want to invoke when the operation successfully completes. (Alternatively you can use an error callback for a failed response.)
If you want to send data back from the server, anything you echo to the response would be available as the first argument to the success function. For example, if you do this on the server:
echo "ud";
Then in the success callback you can show that text:
success: function (result) {
console.log(result);
}
Debated whether to put this on WordPress.SE or here; decided that since it's primarily a jQuery question I'd post it here with the note that it occurred during WordPress development for context.
Long story short, following a guide on how to use AJAX in WordPress to the letter—including pasting in the same code excerpts to see if they run—doesn't work on my dev server. The designated PHP function is never executed, and the call just returns a 0 when I dump the response to a an output div.
I added an error: field to the AJAX call and that triggered, but other than revealing that there was an error, I couldn't figure out what was actually at issue.
Here's a look at the AJAX call, as shown in the guide.
jQuery.ajax({
type : "post",
dataType : "json",
url : myAjax.ajaxurl,
data : {action: "my_user_vote", post_id : post_id, nonce: nonce},
success: function(response) {
if(response.type == "success") {
jQuery("#vote_counter").html(response.vote_count)
}
else {
alert("Your vote could not be added")
}
}
})
Remembering having had this problem before, I decided to review an old project from a year ago, and found the following workaround, which seems to do the same thing, but actually returns the proper response from the script.
Functional workaround, does what is expected
var ajaxurl = '<?php bloginfo('url'); ?>/wp-admin/admin-ajax.php';
var data = {action: "my_user_vote", post_id : post_id, nonce: nonce};
// Handle any returned values
jQuery.post(ajaxurl, data, function(response) {
if(response.type == "success") {
jQuery("#vote_counter").html(response.vote_count)
}
else {
alert("Your vote could not be added")
}
});
Ostensibly, it seems that the latter is just a longwinded way of executing the former, but for some reason only the latter works. What could be causing the error on the first block?
EDIT: It seems this may be a WordPress problem after all. I've already sent the code I was working on the other night to production, so to reproduce it I put it into a plugin and tried to run it on the default theme. It's working on the front end, but it's not working when I take it to a back-end page (which is what I was working on at the time). According to the console, it appears to be an issue with enqueueing the scripts on the back end.
To mitigate that issue, I dumped the following on an otherwise blank back-end page:
This post has <div id='vote_counter'>0</div> votes<br>
<div id="output">Test</div>
<script>
jQuery(document).ready( function() {
jQuery(".user_vote").click( function() {
post_id = jQuery(this).attr("data-post_id")
nonce = jQuery(this).attr("data-nonce")
jQuery.ajax({
type : "post",
dataType : "json",
url : "<?php bloginfo('url'); ?>/wp-admin/admin-ajax.php",
data : {action: "my_user_vote", post_id : post_id, nonce: nonce},
success: function(response) {
jQuery("#output").html(response)
jQuery("#vote_counter").html(5)
},
error: function(response) {
jQuery("#output").html(response)
jQuery("#vote_counter").html(10)}
})
})
})
</script>
<?php
$link = admin_url('admin-ajax.php?action=my_user_vote');
echo '<a class="user_vote" href="' . $link . '">vote for this article</a>';
Long story short: There is no longer any external script to enqueue, the link is coded directly into it, and the count should update to 5 on success or 10 on failure (since this is a back-end page and therefore there's no page_id to check for). All extraneous data fields have been dropped, since they won't be used in this form.
To simplify generating the response, I trimmed the code back to just the following:
function my_user_vote() {
$result = array(
'status' => 'success',
'count' => 5
);
$result = json_encode($result);
echo $result;
die();
}
What now happens is we get redirected to a blank page with the JSON response dumped on it. Tried dropping in the .post() method from above and that's doing the same thing for some reason.
TL;DR: This probably needs a move to wp.se.
I know this question has been asked before several times on this forum, but I think I am missing something. Or maybe it is because I don't know JSON/AJAX that well.
Here is the thing.
I got some javascript/JQuery code on a page, say on index.php, (not yet in a seperate JS file) which let you put any number in an array from 1 to 10. If it's already in it, it will be removed if clicked again.
Now I want to pass that JS array to PHP, so I can create tables with it.
Here's what I have done.
$(".Go").click(function() {
var enc = JSON.stringify(tableChoice);
$.ajax({
method: 'POST',
url: 'calc.php',
data: {
elements: enc
},
success: function(data) {
console.log(enc);
}
});
});
And in my calc.php I got this to get the values to PHP.
<?php
$data = json_decode($_POST['elements'],true);
echo $data;
?>
Now here comes the noob question:
If I click my (.Go) button, what really happens?
Because the console.log let's me see the correct values, but how do I access it? The page (index.php) doesn't automatically go to the calc.php.
When I use a <form> tag it will take me there, but it shows this error:
Undefined index: elements
I am sure I am looking at this the wrong way, interpreting it wrong.
Can someone please help me understand what it is I should be doing to continue with the JS array in PHP.
With a XHR request you don't do a page reload. With your $.ajax method you post data to the server and receive information back. Since you can see information in your console, the success method is triggered.
You might want to take a look at your DevTools in for example Chrome. When you open your Network tab and filter on XHR you see what happens. You can inspect your XHR further by looking into the data you've send and received.
So my question to you is: what do you want to happen onSuccess()? What should happen with the data you receive from your backend?
In JavaScript:
$(".Go").click(function() {
var enc = JSON.stringify(tableChoice);
$.ajax({
method: 'POST',
url: 'calc.php',
data: {
"elements="+enc;
},
success: function(data) {
console.log(data);// You can use the value of data to anywhere.
}
});
});
In PHP:
<?php
if(isSet($_POST[elements]))
{
$data = json_decode($_POST['elements'],true);
echo $data;
}
else
{
echo "Elements not set";
}
?>
I have a form which submits data via AJAX to an external server.
The data which gets sent is then validated and if correct the user can then advance onto the next step of the form.
If the data is not valid, then the server returns an error which is outputted as a JSON object.
I can see the JSON object in FIDDLER.
My aim is to grab that JSON data and output it on the page and notify the user.
Ideally, i would do this as part of an error handler on the AJAX request(found below).
Is this achievable?
PS:
Unfortunately, I can't set up a demo because the link that the data is posted to is only available on my network.
It is also worth pointing out that the error that the back-end script outputs is actually stored in the link that the data is posted to.
AJAX REQUEST:
var setUpVrmData = function() {
$("#getvrmdata").click(function () {
var p_vrm = $('#p_vrm').val();
$.ajax({
dataType: "JSON",
type: "POST",
url: "http://217.35.33.226:8888/l4_site/public/api/v1/BC8F9D383321AACD64C4BD638897A/vdata",
data: {
vrm: p_vrm,
},
success: function(data) {
//Empty the dropdown box first.
$("#p_model").empty();
appendString = "<option value='none'>-- Select your model --</option>";
$.each(data['vehiclemodel'], function (k, v) {
// += concatenate the string
appendString += "<option value='" + k + "'>" + v + "</option>";
});
$("#p_model, #ent_mileage").show();
$('.js-find-my-car').hide();
$('.js-get-price').show();
$("#p_model").append(appendString);
$("#p_model").prop("disabled", false);
$('#skey').val(data['skey']);
},
error: function() {
console.log("We return error!");
}
});
});
The Error function will return an XHR object that you may be able to parse to get the message you want. I don't know what is serving the data so depending on how that's setup your mileage may vary. I've done this using PHP as well as C# and writing to Console, but in both cases I was able to control the returned data.
I used this article : http://encosia.com/use-jquery-to-catch-and-display-aspnet-ajax-service-errors/ as a starting point.
You'll need to update:
error: function() {
console.log("We return error!");
}
to
error: function(xhr, status, error) {
console.log("We return error!");
}
Set a break point there in Firebug to check if an XHR object is passed, if not you'll need to find a way to get it.. You mention you can see the JSON in fiddler, it should be available to you. If it is, just use the eval posed in the article and you should be okay. If not you'll have to go and figure out how to get it, depending on your platform difficulty will vary.
A few things to note, eval is messy and can get you into trouble. In the cases I've done this, I removed the eval in production.
Also as of jQuery 1.8 success error and complete are deprecated. Use done fail and always if you plan on updating jQuery in the future.
jQuery API reference, for reference.
http://api.jquery.com/jquery.ajax/
My users keep complaining that a link does not show up for them. For me, I have tested this on several browsers and it works for me.
What should happen is that a process is started via AJAX using JQuery and once that is done I keep checking with the server via AJAX how much of the process has been done and once the process is complete I show them a link. But a lot of users tell me that it shows them the link and it quickly disappears back to showing 100.0%!
I can't see how I can fix this and I was hoping you guys could help me write something fool proof so that the link is always shown!
Here is the code concerned (its been shortened).
var startTime;
var continueTime;
var done = false;
function convertNow(validURL){
startTime = setTimeout('getStatus();', 6000);
$.ajax({
type: "GET",
url: "main.php",
data: 'url=' + validURL + '&filename=' + fileNameTxt,
success: function(msg){
done = true;
$("#loading").hide("slow");
$("#done").html("LINK SHOWN HERE");
}//function
});//ajax
}//function convertNow
function getStatus()
{
if(done==false){
$.ajax({
type: "POST",
url: "fileReader.php",
data: 'textFile=' + fileNameTxt,
success: function(respomse){
textFileResponse = respomse.split(" ");
$("#done").html("PROGRESS SHOWN HERE IN PERCENTAGES");
}
});//ajax
continueTime = setTimeout('getStatus();', 3000);
}
}
Thanks all
P.S. I have this question before and was given an idea of using a conditional in the function but that didn't work when it should have!!
UPDATE
I have some of my users what OS and browsers they are using and they usually say a Mac Os and firefox or safari. Not sure if that help with the solution.
The behaviour described by the users suggests that the success callback of your getStatus function is called after the one in convertNow. You should test done variable in this callback
function getStatus(){
if(done==false){
$.ajax({
type: "POST",
url: "fileReader.php",
data: 'textFile=' + fileNameTxt,
success: function(respomse){
// FIX : Already done, just ignore this callback
if (done) return;
textFileResponse = respomse.split(" ");
$("#done").html("PROGRESS SHOWN HERE IN PERCENTAGES");
// BONUS : call getStatus only when previous ajax call is finished
continueTime = setTimeout('getStatus();', 3000);
}
});//ajax
}
}
EDIT : This solution should prevent the bug from appearing most of the time, but there is still a chance. The only way to be sure is to remove the callback from convertNow and let the one in getStatus set the link when the processing is done (don't forget to allow only one call to getStatus at a time, see "BONUS" modification above).
If done is never set back to false then the reported behavior would be expected upon the second call to convertNow.
Since the ajax call in convertNow uses GET instead of POST, it is possible that a browser is returning a cached result whenever parameters are identical to a previous call.