Can't get Ajax response - javascript

I am using javascript and php to run an Ajax code.
The result at the moment is undefined.
I am using localStorage to move the variable from the Ajax function because I cannot understand the use of a callback (I have followed numerous examples of using callbacks but none ever worked. I figured this solution might be the least complex.
Javascript:
$( document ).ready(function() {
$('#submit-values').click(function(e){
/************************************************************* SUBMIT */
e.preventDefault();//Stop page reload on click
$('#put-output-here').val(createParagraph());
});
function createParagraph(){
createSentence();
return localStorage.getItem('sentence');
}
function createSentence(){
$.when(ajax1()).done(function(a1){
localStorage.setItem('sentence', a1);
})
}
function ajax1(){
$.post("word-engine.php",
{
},
function(data){
});
}
});
PHP:
<?php
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for($x = 0; $x < 10; $x++){
$rand = rand(0,62);
$randomString = $randomString.$chars[$rand];
}
echo $randomString;
?>
At the moment my result is undefined

use this: since $.post is a asynchronous function. The control from function will immediately return after it run post but the response from post may be received later.
function ajax1(){
$.post("word-engine.php",
{
},
function(data){
setdata(data);
});
}
function setdata(data){
localStorage.setItem('sentence', data);
}
note: for more info see this post:why cant I return data from $.post (jquery)

You need the done event on the $.post function not on the function that's wrapping that function.
E.g.
$.post( "word-engine.php", function( data ) {
localStorage.setItem('sentence', data );
});
On 'done'/return of the ajax post it will put the returned value into your localStorage 'sentence' key. The first param of the post function is the URL of the endpoint, the next is the success handler function. You can then specify more including the callback function handler for failure etc. See docs here for more information.
#suchit makes a good point, you won't be able to access the value in localStorage straight away because post is an async event, the javascript code will move on and the callback will happen when the response is received. You're best displaying your returned localStorage variable to screen inside the success handler or trigger whatever needs to happen with it from there.

Related

Fetching local text file and assign contents to a variable

For as simple as this should be, I have no idea what I am doing wrong. I'm attempting to fetch a local text file and store it in a variable, but regardless of the method (fetch api, $.get and ajax) I use, I always get undefined.
$(document).ready(function() {
var fileConfiguration;
$.get( "Configuration.h", function( data ) {
fileConfiguration = data;
});
document.getElementById("demo").innerHTML = fileConfiguration;
});
The data variable is properly fetched, I can use alert or console.log and see the contents correctly. When I assigned it to a variable though, it's undefined. I imagine this has something to do with it being an asynchronous callback, but can't figure out the problem.
As you and #charlietfl have pointed out the AJAX request is asynchronous which means that the last statement in your code is executed before there's a response, hence fileConfiguration is still undefined.
Therefore the best place to do the assignment is inside the callback like so:
$(document).ready(function() {
$.get( "Configuration.h", function( data ) {
document.getElementById("demo").innerHTML = data;
});
});

How Do I return a javascript variable from a function that contains a $.get() request

I've tried Googling this but could not reslove it. It may seem like a really simple issue to others but I'm baffled by it. I have the below code in which I get undefined for the first alert but I still get the correct values in the 2nd alert. BUT if I comment out the first alert (just the line with alert) then the 2nd alert output becomes undefined. Can any one explain why this is and how I may output the 2nd alert correctly without the first one, any Help is greatly appreciated.
function getDetails(ID){
var qArray = [];
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
});
//First Alert
alert("-> "+qArray[0]);
return qArray;
}
This is the 2nd alert which calls the above method:
var myArray = getDetails(4);
alert("myArray [0]: "+myArray[0]);
You can't return a value, the $.get() call is asynchronous.
You need to defer any operations on qArray until the AJAX call has completed, i.e. inside the callback.
Better yet, use deferred callbacks:
function getDetails(ID) {
return $.get('get_Question', {"Id":ID})
.pipe(function(json) {
return [json.value1, json.value2];
});
}
The .pipe deferred function creates a new promise which will ultimately return the desired array, but only once the AJAX call has completed.
You would then use this like this:
getDetails(ID).done(function(qArray) {
alert("-> " + qArray[0]);
});
Note that $.get() doesn't directly support error callbacks, but with deferred objects you can get access to them:
getDetails(ID).done(function(qArray) {
alert("-> " + qArray[0]);
}).fail(function(jqXHR, textStatus, errorThrown)) {
alert("The AJAX request failed:" + errorThrown);
});
Without this you'd need to build the error handling directly into the getDetails() function and then require some mechanism to tell the rest of the application logic about the error.
NB I've assumed that you don't really need to call JSON.parse() manually - if your web server returns the right Content-Type header then jQuery will do that for you automatically.
Ajax calls happens asynchroniusly, meaning you can't wait for the call to return and get the value. The way to do it is to employ a callback. Your example will become something similar to this:
function getDetails(ID, callback){
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var qArray = [];
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
callback(qArray)
});
}
Calling it will change a bit:
getDetails(4, function (myArray) {
alert("myArray [0]: "+myArray[0]);
});
The First Alert is called before the ajax call is finished, so the variable is still undefined.
This is because the $.get() is done asynchronously. There is no option for $.get() to pass parameter for async calls, so you should use $.ajax() instead and pass a param async: false
The $.get call creates a new asynchronous request for the resource in question.
When you call the first alert it is undefined because the request hasn't been completed yet. Also since you are forced to pause on the alert the request has time to be completed in the background. Enough time for it to be available by the second alert.
The same thing happens when you comment out the first alert. This time the second alert is called before the request is completed and the value is undefined.
You need to either make your requests synchronous or consider continuing execution after receiving the response by using a callback function within the success callback function you have already defined in $.get.
As several others have said, ajax-request are asynchronous. You could however set the async property to false to get a synchronous request.
Example:
function getDetails(ID) {
var result = $.ajax('get_Question', {
async : false,
data : { 'Id' : ID }
});
// do something with the result
return result;
}
I myself would have use a callback function instead beacuse async:false is bad practice and is also deprecated.
You'll need to rewrite $.get to use $.ajax and specify async: false
AJAX is asynchronous: you can't tell when the request will complete. This usually means you need to pass callback methods that will be called with the result of the request when it completes. In your case this would look something like:
function getDetails(ID, callbackFunc){
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var qArray = [];
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
callbackFunc(qarray);
});
}
getDetails(4, function(qArray) {
alert("myArray [0]: "+qArray[0]);
};

Retrieve variable set within getJSON callback function

I am forced to use data from within the getJSON callback function outside of that function. Have a look:
$('#stars').raty({
score: function() {
var $value = 0;
var $id = <?=$id?>;
$.getJSON("getuserrating.php?id=" + $id, function(data) {
$.each(data, function(key, val) {
$value = val;
});
});
return $value;
},
});
This is what I tried but it failed, the $value is still set to 0, although inside the callback it's definitely set to an actual value. I know why it fails, because the AJAX request is send asynchronously. The problem is, the correct way, doing everything inside the callback, is not possible. As you can see I need to retrieve the JSON object within the raty (a plugin) setup. I would just use $.ajax() and set that to synchronous but the documentation marks this as deprecated for 1.8. I'd rather not introduce a solution that I know will be deprecated in the future.
Is there any way at all to do this? Maybe I just don't see the forest for the trees and there's an easy solution right before me. Thanks in advance :)
Approach is backwards if you need to use ajax to get the score.
Make the ajax call first, then pass the value to score within the ajax success
$.getJSON("getuserrating.php?id=" + $id, function(data) {
/* pseudo code here since I don't know the plugin and it's data requirments*/
var score= data.score;
$('#stars').raty({
score: score
});
});
EDIT: you can still pass the data into a score function this way also
Maybe this (taken from jquery getJSON api doc http://api.jquery.com/jQuery.getJSON/) could work:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON("example.json", function() {
alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
// perform other work here ...
// Set another completion function for the request above
jqxhr.complete(function(){ alert("second complete"); });
Just assign another raty attribute instead of returning.

getJSON to string then loop through string

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)
});

Return value from Ajax callback?

I have a JavaScript class that handles queries to a local DB (on a WebOs device). Now what I want to do is, create a model with all my basic queries to simplify my code.
So first I create a function:
getLists: function(){
this.query( 'SELECT * FROM lists ORDER BY rowID DESC', {
onSuccess: enyo.bind(this,function(data) { this.getData(data); } ),
onError: function() { return false; } } );
}
And than I have my callback function which receives the data:
getData: function(data){
return data;
}
Now what I would like to do, is call it like this from my app:
var data = getLists();
The problem is, this is not returning the data from my callback function (getData). My question is how can I have "getLists" return the data from the callback?
Thank you
You're thinking imperial: C follows B follows A. Forget about that.
AJAX and modern JavaScript works differently. You never say "get data now", you say "call X when data is available".
So the solution is to write some code which does something useful with the data. Let's call this function a. Instead of:
var data = conn.getData();
a( data );
b( data );
c( data );
you do
conn.getData( a ); // a has to call b which calls c.
Eventually, the data will be there and a will be called with data as an argument.
See? You don't chain calls to a() and b() as in traditional programming. Instead, you create functions that do what you want and pass those functions around.
You don't get to. The first A in AJAX is Asynchronous. The requests happen "out of time" with the other processing. Your call to getLists returns after it launches the AJAX request, and the callback function is called when the remote server responds to the AJAX request.
-- Edited for comments --
If you want to "watch" a variable you can use something like this:
// Set up a container for the data to return to.
var retData;
// Modify the getData function to assign to the global variable
getData: function (data) {
retData = data;
}
// Start the "wait" process.
var myInterval = setInterval(function () {
if (retData == undefined) {
return;
}
// when the return data shows up stop waiting.
clearInterval(myInterval);
// some other data processing here in this function
// or trigger the actual processing function.
// don't have to pass retData to it, it's global, the
// data handler function can retrieve it itself.
myDataHandler();
}, 1000);
// make the ajax call here.
getLists();

Categories

Resources