Can't declare variable from JSON/jQuery object - php

So, I'm able to return my AJAX request successfully, but my jQuery seems to die once I declare a variable from it.
Here's my JSON response from the console:
Object {readyState: 4, responseText: "{"rsp":"1","msg":"show out screen!","time":null,"fn":"Mike","ln":"Maynard","ul":"0"}", status: 200, statusText: "success"}
Here's my jQuery:
$.ajax({
url: "clock.php",
type: "POST",
async: false,
data: clockData,
cache: false,
timeout: 5500,
error: function (clockData) {
//var rsp = (clockData.fn);
alert('Error');
//do error
},
dataType: 'json',
complete: function (clockData) {
console.log(clockData);
var rsp = clockData[0].rsp;
console.log(rsp);
var ul = clockData[0].ul;
if(ul=='1') {
showUi();
}
var una = (clockData.fn + ' ' + clockData.ln);
$('.nameBlock').text(una);
$('.nameBlockFirst').text(clockData.fn);
//--> show in ui
if (rsp=='0') {
console.log('got here2');
var dir = 'In'; tcShow(dir);
}
//--> show out ui
if (rsp=='1'){
alert('trying to show out screen2');
var dir = 'Out'; tcShow(dir);
}
//--> show in result
else if (rsp=='2'){
var time = (clockData.time); var dir = 'in'; showResult(time,dir,ul);
}
//--> show out result
else if (rsp=='3'){
var time = (clockData.time); var dir = 'out'; showResult(time,dir,ul);
}
//--> show message
else if (rsp=='4'){
endClock();
}
else {
endClock();
}
}
});
So, console.log(clockData); Returns fine, but console.log(rsp); Never happens... I'm confused..

Based off your response text, it looks like it should be clockData.rsp. You are doing clockData[0].rsp which would imply that clockData is an array. But in fact, your response is a keyed object, not an array.
EDIT: I just noticed you are also using the complete method, not success. complete has a method signature of (jqXHR, textStatus). If you want the response data, you can access it through JSON.parse(clockData.responseText), or better yet, use the success callback which has a method signature of (responseData, textStatus, jqXHR). Or for a more modern approach, use promises.
REF: http://api.jquery.com/jquery.ajax/

Related

Save Ajax JQuery selector in an array

I'm very new with Ajax and I need help to store the data from an Ajax request into an array. I looked at answers here at the forum, but I'm not able to solve my problem.The Ajax response is going into $('#responseField').val(format(output.response)) and I'm want store "output.response" into an array that can be used outside of the Ajax. I tried to declare a variable outside of the Ajax and call it later, but without success. I'm using $json_arr that should get the data. How do I do to get the data from the Ajax and store it in a variable to be used outside of the Ajax? This variable will an array that I can access the indexes.
function sendRequest(postData, hasFile) {
function format(resp) {
try {
var json = JSON.parse(resp);
return JSON.stringify(json, null, '\t');
} catch(e) {
return resp;
}
}
var value; // grade item
$.ajax({
type: 'post',
url: "doRequest.php",
data: postData,
success: function(data) { //data= retArr
var output = {};
if(data == '') {
output.response = 'Success!';
} else {
try {
output = jQuery.parseJSON(data);
} catch(e) {
output = "Unexpected non-JSON response from the server: " + data;
}
}
$('#statusField').val(output.statusCode);
$('#responseField').val(format(output.response));
$("#responseField").removeClass('hidden');
data = $.parseJSON(output.response)
$json_arr=$('#responseField').val(format(output.response));
},
error: function(jqXHR, textStatus, errorThrown) {
$('#errorField1').removeClass('hidden');
$("#errorField2").innerHTML = jqXHR.responseText;
}
});
}
window.alert($json_arr);
let promise = new Promise(function(resolve, reject) {
$.ajax({
type: 'post',
url: "doRequest.php",
data: postData,
success: function(data) { //data= retArr
var output = {};
if(data == '') {
output.response = 'Success!';
} else {
try {
output = jQuery.parseJSON(data);
} catch(e) {
output = "Unexpected non-JSON response from the server: " + data;
}
}
$('#statusField').val(output.statusCode);
$('#responseField').val(format(output.response));
$("#responseField").removeClass('hidden');
data = $.parseJSON(output.response)
resolve(format(output.response));
},
error: function(jqXHR, textStatus, errorThrown) {
$('#errorField1').removeClass('hidden');
$("#errorField2").innerHTML = jqXHR.responseText;
}
});
});
promise.then(
function(result) { /* you can alert a successful result here */ },
function(error) { /* handle an error */ }
);
The issue is you are calling asynchronously.
You call the alert synchronously, but it should be called asynchronously.
A little snippet to help you see the difference:
// $json_arr initialized with a string, to make it easier to see the difference
var $json_arr = 'Hello World!';
function sendRequest() {
$.ajax({
// dummy REST API endpoint
url: "https://reqres.in/api/users",
type: "POST",
data: {
name: "Alert from AJAX success",
movies: ["I Love You Man", "Role Models"]
},
success: function(response){
console.log(response);
$json_arr = response.name;
// this window.alert will appear second
window.alert($json_arr);
}
});
}
sendRequest();
// this window.alert will appear first
window.alert($json_arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Send data from Javascript to PHP and use PHP's response as variable in JS

I have checked around, but can't seem to figure out how this is done.
I would like to send form data to PHP to have it processed and inserted into a database (this is working).
Then I would like to send a variable ($selected_moid) back from PHP to a JavaScript function (the same one if possible) so that it can be used again.
function submit_data() {
"use strict";
$.post('insert.php', $('#formName').formSerialize());
$.get('add_host.cgi?moid='.$selected_moid.');
}
Here is my latest attempt, but still getting errors:
PHP:
$get_moid = "
SELECT ID FROM nagios.view_all_monitored_objects
WHERE CoID='$company'
AND MoTypeID='$type'
AND MoName='$name'
AND DNS='$name.$selected_shortname.mon'
AND IP='$ip'
";
while($MonitoredObjectID = mysql_fetch_row($get_moid)){
//Sets MonitoredObjectID for added/edited device.
$Response = $MonitoredObjectID;
if ($logon_choice = '1') {
$Response = $Response'&'$logon_id;
$Response = $Response'&'$logon_pwd;
}
}
echo json_encode($response);
JS:
function submit_data(action, formName) {
"use strict";
$.ajax({
cache: false,
type: 'POST',
url: 'library/plugins/' + action + '.php',
data: $('#' + formName).serialize(),
success: function (response) {
// PROCESS DATA HERE
var resp = $.parseJSON(response);
$.get('/nagios/cgi-bin/add_host.cgi', {moid: resp });
alert('success!');
},
error: function (response) {
//PROCESS HERE FOR FAILURE
alert('failure 'response);
}
});
}
I am going out on a limb on this since your question is not 100% clear. First of all, Javascript AJAX calls are asynchronous, meaning both the $.get and $.post will be call almost simultaneously.
If you are trying to get the response from one and using it in a second call, then you need to nest them in the success function. Since you are using jQuery, take a look at their API to see the arguments your AJAX call can handle (http://api.jquery.com/jQuery.post/)
$.post('insert.php', $('#formName').formSerialize(),function(data){
$.get('add_host.cgi?moid='+data);
});
In your PHP script, after you have updated the database and everything, just echo the data want. Javascript will take the text and put it in the data variable in the success function.
You need to use a callback function to get the returned value.
function submit_data(action, formName) {
"use strict";
$.post('insert.php', $('#' + formName).formSerialize(), function (selected_moid) {
$.get('add_host.cgi', {moid: selected_moid });
});
}
$("ID OF THE SUBMIT BUTTON").click(function() {
$.ajax({
cache: false,
type: 'POST',
url: 'FILE IN HERE FOR PROCESSING',
data: $("ID HERE OF THE FORM").serialize(),
success: function(data) {
// PROCESS DATA HERE
},
error: function(data) {
//PROCESS HERE FOR FAILURE
}
});
return false; //This stops the Button from Actually Preforming
});
Now for the Php
<?php
start_session(); <-- This will make it share the same Session Princables
//error check and soforth use $_POST[] to get everything
$Response = array('success'=>true, 'VAR'=>'DATA'); <--- Success
$Response = array('success'=>false, 'VAR'=>'DATA'); <--- fails
echo json_encode($Response);
?>
I forgot to Mention, this is using JavaScript/jQuery, and ajax to do this.
Example of this as a Function
Var Form_Data = THIS IS THE DATA OF THE FORM;
function YOUR FUNCTION HERE(VARS HERE) {
$.ajax({
cache: false,
type: 'POST',
url: 'FILE IN HERE FOR PROCESSING',
data:Form_Data.serialize(),
success: function(data) {
// PROCESS DATA HERE
},
error: function(data) {
//PROCESS HERE FOR FAILURE
}
});
}
Now you could use this as the Button Click which would also function :3

Why is this returning me 'undefined' [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 10 years ago.
Trying to run a script, (test.al();) and inside test.al, its called getcrypt.php();, the php script is on a webserver, and it is working. Currently, these are my scripts
JS
var getcrypt = {
php: function () {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
return v;
}
});
}
}
var test = {
al: function () {
a = getcrypt.php();
alert(a);
}
}
PHP
<?php
$id = $_POST['id'];
if ('getit' == $id){
$value = 'VALUE';
echo $value;
}else{
echo 0;
}
?>
In this way, it will show an alert with 'unidefined', and if i add a alert(v); right before return v, it will show me 'VALUE', but not able to use it outside the variable...
var getcrypt = {
php: function () {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
alert(v);
return v;
}
});
}
}
This will give me an alert with the correct value (AFTER THE 'undefined')
This is because of the asynchronous call you're making. The return is only for the success function and not for the php function.
To get the value out you would need to write:
var value;
var getcrypt = {
php: function (callback) {
$.ajax({
url: "",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
alert(v);
callback(v);
}
});
}
}
getcrypt.php(function(v) {
alert(v);
// This happens later than the below
value = v;
});
// The below will still not work since execution has already passed this place
// alert will still return undefined
alert(value);
The problem is jQuery ajax works with callbacks and does not work with return value's so you need to add an callback to your getcrypt function so say
var getcrypt = {
php: function (callback) {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
callback(v);
}
});
}
}
so now if you call
getcrypt.php(function(returnVar){
alert(returnVar)
});
you will get an alert with VALUE
$.ajax returns immidiately (well, almost :)) upon calling, before the response is received. You should rewrite your code to accomodate to this fact, something like this;
var getcrypt = {
php: function(){
$.ajax({
//..other params ..//
success: function(msg){
var v = msg.match(/^.*$/m)[0];
alertResponse(v);
}
});
},
alertResponse: function(processedResponse) {
alert(v);
}
}
var test = {
al: function(){
getcrypt.php();
}
}
If you need your response in test object, you move alertResponse to that object and call it from success method. I think this tutorial might be useful for you to learn javascript event-driven programming model.
$.ajax calls are async. So what you get is the return value of $.ajax (when the request is sent, before a response is received). It is only when the browser receives a response to the ajax call that the success callback is run, as a seerate process from the $.ajax call. In other words the return value of $.ajax will always be null. I'm not sure it's possible to do anythging with the return value of the success callback, you need to put your logic (or a call to another function with the logic) in the success callback itself, in the same way you did with the alert in your final example

Why won't my .ajax request work?

The code I want to work:
$.ajax({
type: "POST",
url: "_Source/ajap/ajap.nlSrch.php",
data: { sndJson : jsonData },
dataType: "json",
processData: false,
success: function(html) {
$("#srchFrm").append(html);}
});
The code that works:
$.ajax({
type: "POST",
url: "_Source/ajap/ajap.nlSrch.php",
data: { sndJson : jsonData },
success: function(html) {
$("#srchFrm").append(html);}
});
Unfortunately when I send the first one my post data looks like this "Array ()" and when I use the later I get this "Array ( [sndJson] => [\"8\",\"3\",\"6\",\"7\"] )".
I know that there has to be a simple explanation but I haven't been able to figure it out.
Help please!
Try sending your data in a query string...
$.ajax({
type:"POST",
url:"_Source/ajap/ajap.nlSrch.php?json="+jsonData,
dataType:"json",
success: function(data) {
$("#srchFrm").append(data);}
error: function(xhr, ajaxOptions, thrownError)
{alert("Error!");}
});
You can use shorthand $.post instead of using low level ajax class --- because you don't need to advanced handling. So, this one will be great enough.
$(document.ready(function(){
$("#submit_button").click(function(){
$.post('php_script.php', {
// here's what you want to send
// important -- double quotes, 'cause It's evals as valid JSON
"var1" : "val1"
"var2" : "val2"
}, function (respond){
try {
var respond = JSON.parse(respond);
} catch(e){
//error - respond wasn't JSON
}
});
});
});
PHP code:
<?php
/**
* Here you can handle variable or array you got from JavaScript
* and send back if need.
*/
print_r($_POST); // var1 = val1, var2 = val2
?>
Back to your question,
Why my .ajax request doesn't work?
This is because JavaScript throws fatal error and stops further code execution.
You can catch and determine the error occasion, simply by adding
try {} catch(){} block to the statement you think may occur any error
When you specify dataType: json, jQuery will automatically evaluate the response and return a Javascript object, in this case an array. You're taking the result and adding it as html to #srchForm, so it does not make sense to convert it to a javascript object. Use dataType: html, or none at all.
http://api.jquery.com/jQuery.ajax/
The following examples above are not reusable. I am a huge fan of reuseable code. here is my solution.
Software design 101:
DRY Don't repeat your self. You should wrap your code into an object. This way you can call it from anywhere.
var Request = {
version: 1.0, //not needed but i like versioning things
xproxy: function(type, url, data, callback, timeout, headers, contentType)
{
if (!timeout || timeout <= 0) { timeout = 15000; }
$.ajax(
{
url: url,
type: type,
data: data,
timeout: timeout,
contentType: contentType,
success:function(data)
{
if (callback != undefined) { callback(data); }
},
error:function(data)
{
if (callback != undefined) { callback(data); }
},
beforeSend: function(xhr)
{
//headers is a list with two items
if(headers)
{
xhr.setRequestHeader('secret-key', headers[0]);
xhr.setRequestHeader('api-key', headers[1]);
}
}
});
}
};
Usage:
<script type="text/javascript">
var contentType = "applicaiton/json";
var url = "http://api.lastfm.com/get/data/";
var timeout = 1000*5; //five seconds
var requestType = "POST"; //GET, POST, DELETE, PUT
var header = [];
header.push("unique-guid");
header.push("23903820983");
var data = "{\"username\":\"james\"}"; //you should really deserialize this w/ a function
function callback(data)
{
//do logic here
}
Request.xproxy(requestType, url, data, callback, timeout, header, contentType);
</script>

JQuery ajax function works but can't return the variable correctly

I have a function runAjax that functions correctly. Unfortunately I am struggling to return the value I get from the ajax query.
The ajax function assigns the returned value inside "contents" or "error" xml tags to the variable "result".
If I alert the result variable inside the ajax function it alerts the correct value (i.e if the xml value inside contents is "published" it alerts published).
However if I alert the returned value from the runAjax function it alerts an object instead of the value of the internal variable "result" which in the above example is "published".
function runAjax (data_obj){
return $.ajax({
url:"/ajax.php",
dataType: "xml",
data: data_obj,
success: function(data) {
// format result
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
var result;
if($("error",xml).text()){
result = [$("error",xml).text()];
} else{
result = [
$("contents", xml).text()
];
}
alert(result); //alerts the correct string for example "published"
return result;
}
});
}
$('ul.content li span.changeable').click(function(e){
e.preventDefault();
var method_set = $(this).parent().attr("class");
var id_set = $(this).parent().parent().find('li.id span').html();
var user = $(this);
var result = runAjax({method: method_set, id: id_set});
alert(result); //alerts an object not published
});
Im sure it has something to do with the way I am returning the variable but I can't figure it out. Any input would be much appreciated.
Regards
Luke
UPDATE:
This is the revised code that works thanks to all the input from people below:
function runAjax (data_obj,callback){
$.ajax({
url:"/ajax.php",
dataType: "xml",
data: data_obj,
success: function(data) {
// format result
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
var result;
if($("error",xml).text()){
result = [$("error",xml).text()];
} else{
result = [
$("contents", xml).text()
];
}
if ( typeof(callback) == "function") {
callback(result);
}
}
});
}
$('ul.content li span.changeable').click(function(e){
e.preventDefault();
var method_set = $(this).parent().attr("class");
var id_set = $(this).parent().parent().find('li.id span').html();
var user = $(this);
runAjax({
method: method_set,
id: id_set
},
function(result){
$(user).html(result.join('')); //this is instead of alert(result);
}
);
});
According to the docs
The $.ajax() function returns the XMLHttpRequest object that it creates.
Any return value that you return from the success callback function is ignored.
You need to put the value in a variable defined in a wider scope than inside the callback function (global, or preferably inside an outer function).
var result;
$.ajax({
....
success : function(data) {
...
result = ...;
}
});
Or better yet: do whatever you want to do with the return value inside the success callback function, this will keep the asynchronous nature of the ajax call and means you don't need to wait for the call to come back.
Doing your processing in the success callback function means you know you have the results, if you put the value in a variable the variable may not be assigned a value yet by the time you want to use it.
In a comment to another answer on this page you say:
however I am calling the runAjax function from multiple other functions not just the one in my code example above, so I need the value returned rather than the runAjax function doing the html replacing
I would add an extra parameter to your runAjax function, which is another callback function that you can pass in different processing functions from the various functions.
function runAjax(data_obj, callback) {
$.ajax({
...
success : function(data) {
...
result = ...
...
if ( typeof(callback) == "function") {
callback(result);
}
}
});
}
Then you can call it like
runAjax({method: method_set, id: id_set},
function(result){
alert(result);
}
);
Then you can do your generic processing of the data in the success function, but the custom processing for each call in the callback function.
If you really need to wait for the call, you can create a synchronous ajax call by passing the async option:
$.ajax({
async:false,
....
Luke,
Basically, create a wrapper function for your $.ajax() call with a parameter for the callback portion (you could of course have parameters for any valid paramter in the ajax call. here's a quickie to demonstrate:
function runAjax (data_obj, callback){
$.ajax({
url:"/ajax.php",
dataType: "xml",
data: data_obj,
success: function(data) {
if (data != null && callback !== null ) {
callback(data);
}
}
});
}
function callbackFunction (data) {
// format result
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
var result;
if($("error",xml).text()){
result = [$("error",xml).text()];
} else{
result = [
$("contents", xml).text()
];
}
alert(result); //alerts the correct string for example "published"
// do your DOM updates etc here
}
$('ul.content li span.changeable').click(function(e){
e.preventDefault();
var method_set = $(this).parent().attr("class");
var id_set = $(this).parent().parent().find('li.id span').html();
var user = $(this);
runAjax({method: method_set, id: id_set}, callbackFunction);
});
hope this helps..
Luke,
I think you're assigning the retrun value at the wrong point in the function, you should really have a single exit point before the final curly brace. you're returning the result technically as a return value of the $.ajax() function (an XMHTTP object), NOT the parent method.
try this instead:
function runAjax (data_obj){
var returnValue;
$.ajax({
url:"/ajax.php",
dataType: "xml",
data: data_obj,
success: function(data) {
// format result
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
var result;
if($("error",xml).text()){
result = [$("error",xml).text()];
} else{
result = [
$("contents", xml).text()
];
}
alert(result); //alerts the correct string for example "published"
returnValue = result;
}
});
return returnValue;
}
$('ul.content li span.changeable').click(function(e){
e.preventDefault();
var method_set = $(this).parent().attr("class");
var id_set = $(this).parent().parent().find('li.id span').html();
var user = $(this);
var result = runAjax({method: method_set, id: id_set});
alert(result); //alerts an object not published
});
The reason that you can't get the result returned correctly is because of the asynchronous nature of AJAX (that's what the first 'A' stands for).
The call to runAjax() probably returns long before the AJAX operation completes and the 'success' handler is invoked. The runAjax() call returns a referenc to the XMLHttpRequest object that was used to invoke the AJAX communication. The return value from the success handler cannot be used by you directly, as it returned to the internal working of the $.ajax() code.
A suitable solution would depend on what you want to do with 'result' - I'm guessing that 'alert(result)' is only for illustration purposes.
Luke,
To further refine the answers provided by myself and Jim, considering that the result parsing bit is likely to be consistent for each of the different calls...
function runAjax (data_obj, callback){
$.ajax({
url:"/ajax.php",
dataType: "xml",
data: data_obj,
success: function(data) {
if (data != null && callback !== null ) {
// format result
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
var result;
if($("error",xml).text()){
result = [$("error",xml).text()];
} else{
result = [$("contents", xml).text()];
}
callback(result);
}
}
});
}
function callbackFunction (result) {
alert(result); //alerts the correct string for example "published"
// do your DOM updates etc here
}
$('ul.content li span.changeable').click(function(e){
e.preventDefault();
var method_set = $(this).parent().attr("class");
var id_set = $(this).parent().parent().find('li.id span').html();
var user = $(this);
runAjax({method: method_set, id: id_set}, callbackFunction);
});
You can handle the success of the ajax call as an event which keeps the good stuff of the async call including stuff based on the url you called.
$('ul.content li span.changeable').ajaxSuccess(function(e, xhr, settings) {
if (settings.url == '/ajax.php') {
$(this).text('Triggered ajaxSuccess handler.');
someglobalresultvariable = xhr.responseXML; // the xml of the response
$(this).text(someglobalresultvariable);
}
});
Here I make the wild assumption that you want to change the span content text based on the clicked item.
NOTE: I replaced the "triggered" text message and only show that as an example. You can decide how you wish to handle the result.
try removing [ and ]
if($("error",xml).text()){
result = $("error",xml).text();
} else{
result = $("contents", xml).text();
}

Categories