JS — Trying to return AJAX data - javascript

I've been struggling with getting the data out of an AJAX call using jQuery. I'm using RequireJS so my JavaScript can be more maintainable/modular. I've only been using RequireJS for a few days, so I may or may not be doing this right. Just looking for a way to keep my JS modular and clean.
Here is what I have so far. I know for a fact that it's getting the correct data because if I console.log(data[Math.floor(Math.random()*data.length)]), the data is there. The JSON file is long so I won't show you that, just take my word for it — it works.
var maze;
define(["jquery"], function($){
$.ajax("js/mazes.json", {
dataType: "json",
type: "get",
success: function(data){
var maze = data[Math.floor(Math.random()*data.length)];
}
});
return {
randomMaze: maze
};
});
I also tried this (declaring maze within anonymous function)
define(["jquery"], function($){
var maze;
$.ajax("js/mazes.json", {
dataType: "json",
type: "get",
success: function(data){
var maze = data[Math.floor(Math.random()*data.length)];
}
});
return {
randomMaze: maze
};
});
I don't know what I'm doing wrong. Just trying to return data[Math.floor(Math.random()*data.length)]

jQuery.ajax() success returns results asynchronously , maze may not be defined when called synchronously outside of success at
return {
randomMaze: maze
};
Try returning jQuery promise object $.ajax() from function , returning object within asynchronous success callback
// return jQuery promise object
return $.ajax("js/mazes.json", {
dataType: "json",
type: "get",
success: function(data){
// return object as jQuery promise value
return {
randomMaze: data[Math.floor(Math.random()*data.length)];
}
}
});
See also How do I return the response from an asynchronous call?

Related

generalizing ajax call into function

I'm trying to attempt to generalize my ajax calls into a function as follows. I have not done this before and am not sure sure if I'm doing it correctly.
<script>
$(document).ready(function(){
var reg_no=$("#reg_no").val();
reg_no=reg_no.trim();
if(reg_no!==""){
//populate fields
data={reg_no:reg_no,func:"getSupplierDetails"};
success_function="updateFormFields";
ajax_call(data,success_function);
}
});
function ajax_call(data,success_function){
$.ajax({
type:"POST",
url:"../control/supplier-c.php",
dataType:"json",
data:data,
success:function(data){
success_function(data); //variable function works??
}
});
}
function updateFormFields(data){
//some code here to handle data array
}
</script>
What I'm trying to do here is avoid rewriting the whole ajax code by passing the data array and the function to be executed on success. What I'm not sure is the use of variable functions as i have done.
A note to be made is that the whole thing works for an ajax call if updateFormFields() code was moved into the success handler in the ajax call and the ajax_call() was not defined as a seperate function but implemented right after the comment "populate fields". I just have no experience in trying it this way and I need to know if this is possible or not.
Thank You
In Javascript, functions are first class objects, meaning you can pass them around as parameters.
function json_post(url, data, success_function, error_function) {
$.ajax({
type:"POST",
url:url,
dataType:"json",
data:data
}).then(success_function, error_function);
}
Then you can call it as
json_post("../control/supplier-c.php", { data: "data" }, function (res) {
console.log('Ajax req successful');
console.log(res);
}, function (res) {
console.log('Error in ajax req');
console.log(res);
});
In your case, you can do:
ajax_call(data, updateFormFields);
and it should work as expected.
There's no need to wrap the success function, you can just apply apply it directly.
function ajax_call(data, success_function) {
$.ajax({
...
success: success_function
});
}
An even better idea is to avoid the legacy success and error callbacks and instead return the jQuery promise. You can use standard promise methods .then() and `.
function ajax_call(data) {
return $.ajax({
...
});
}
ajax_call()
.then(function(data) {
// this runs if it succeeds
})
.fail(function(err) {
// this runs if it failed
});
Promises have a huge benefit to being chain-able, making the code flatter, avoiding the nest of "christmas tree callbacks".
I would recommend checking success_function as well as failure_function to handle server response (XHR) errors also.
function success_function(){
//code to handle success callback
}
function error_function(){
//code to handle failure callback
}
function ajax_call(data, success_function, error_function) {
if (typeof success_function === 'function' && typeof error_function === 'function') {
$.ajax({
type: "POST",
url: "../control/supplier-c.php",
dataType: "json",
data: data,
}).then(success_function).fail(error_function);
}
}

Basic jquery deferred usage with ajax

I am trying to rewrite code from How to capture asynchronous ajax response into a variable? to use jquery deferred functions. I started with :
var html ="";
$.ajax({
type:"POST",
url: "Ajax/getHtml",
data: { u : contents },
dataType: 'html',
success: function(data) {
html = data;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('error');
console.log(jqXHR,textStatus, errorThrown);
}
});
console.log('html', html);
I am trying to turn this into a deferred function which can be resolved when the requested html page is returned. I have been reading http://learn.jquery.com/code-organization/deferreds/examples/ and http://jqfundamentals.com/chapter/ajax-deferreds to do this. So far I've come up with :
var html_response = new $.Deferred(url){
$.ajax({
type:"POST",
url: "Ajax/getHtml",
data: { u : url},
dataType: 'html',
success: html_response.resolve,
error: html_response.reject
});
};
This would be used as part of :
html_response().done{
console.log('html', html);
}
What I am trying to do is when the get_html function returns html sucessfully (i.e get_html is resolved )grab the html and send it to the console. I'm having trouble figuring out how to put the pieces together here. Could someone advise me please.
What you are doing has the right concept.
If I understand correctly, you are trying to do some "true asynchronous" ajax, unlike your last post.
The one thing you are doing incorrectly is resolving your deferred jQuery variable.
The correct code should look like this:
var html_response = $.Deferred(); // no need for new
function get_html(url){
$.ajax({
type:"POST",
url: "Ajax/getHtml",
data: { u : url},
dataType: 'html',
success:function(data) {
html_response.resolve(data); //resolve is a fn
},
error: function(x, status, err) {
html_response.reject(err); //reject is a fn
}
});
};
}
get_html(inserturlhere);
html_response.done(function(html){ // handle success
console.log('html: ' + html);
})
.fail(function(error) { // handle failure
console.log(error);
});
However, ajax comes explicitly with a defer already, so be sure to check that out first. http://api.jquery.com/jquery.ajax/
This works because $.ajax returns it's own promise (like animations), negating the need to create your own deferred object.
function html_response(url){
return $.ajax({
//ajax stuff
});
}
html_response(url).done(function(data){
console.log(data);
});
You don't need a full Deferred here. You just need a Promise, whose interface is a subset of that of a Deferred (see the doc on Deferred for more info). The promise has a method .done() that lets you provide a callback to be executed when the asynchronous process ends successfully.
The $.ajax() method returns a jqXHR object which conveniently implements the Promise interface:
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the
Promise interface, giving them all the properties, methods, and
behavior of a Promise
So when you call $.ajax, you already have a promise. Just do:
$.ajax({
...
}).done(function(data){
console.log(data);
});
Alternatively, if you really want to deal with a full Deferred object, you could do:
var defr = $.Deferred();
defr.done(function(data){
console.log(data);
});
$.ajax({
...
,sucCess : function(data){
defr.resolve(data);
}
});

how to use properties and methods withing a JavaScript class to exchange data?

i have small issue with exchanging data in between methods in a JavaScript object (class):
var TEST = (function () {
var TEST = function() {
};
TEST.prototype.get = function() {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: function (data) {
return data; // if i console log this i will get a json obj
}
});
};
TEST.prototype.parse = function(data) {
$.each(this.get(), function(k, v){
console.log(v);
});
};
return TEST;
})();
so i am trying to call one method in the each statement in another method. the issue is that
the response is undefined.
i also tried it like this, but with he same result
var testing = new TEST();
var get = testing.get();
testing.parse(get);
What am i missing? how can i return the data from this.get to be used in this.parse.
thanks
$.ajax() per default is asynchronous. That means, that the execution of your function get() wont wait until the request is finished. Hence you return no value from it, which results in undefined being returned.
In order to have your get() function be able to return a value, you would have to do the request in a synchronous way and set a variable in the outer function (as success itself is just another function, whose return value is not caught):
TEST.prototype.get = function() {
var result;
$.ajax({
type: "GET",
url: "http://test.com/getall",
async: false, // this is the important part!
dataType: "json",
success: function (data) {
result = data;
}
});
return result;
};
EDIT
As mentioned by #pebbl, this will halt the execution of all your scripts, until the request is done. Hence your whole page will be blocked for the time being.
The general approach is to use callbacks in such cases, which will be executed once the requests finished. So in your case something like this:
TEST.prototype.get = function( cb ) {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: function (data) {
cb( data );
}
});
};
with later on calling like this:
var testing = new TEST();
testing.get( function( data ) {
testing.parse( data );
});
You can't construct your function this way as you are relying on an asyncronous call, which will return it's result outside of the normal execution flow. The only way you can actually receive the result of your .get function is to use a callback.
Put simply your value isn't being returned from the .get function, it's being returned from the callback you are passing into jQuery's .ajax method.
You'd be far better off redesigning your code so as to still support the asyncronous call -- rather than disabling async.
A rough idea is to change your parse function like so:
TEST.prototype.parse = function(data) {
this.get(function(result){
$.each(result, function(k, v){
console.log(v);
});
});
};
And to change your get function accordingly:
TEST.prototype.get = function(callback) {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: callback
});
};
The above is just a quick example, you'd be wise reading up on the following jQuery topics:
http://api.jquery.com/promise/
http://api.jquery.com/category/deferred-object/
If you design your code around the promise pattern you'll find it complicated at first, but it gives you a lot of power in your code -- and gets around the whole callback stacking madness you can end up with when dealing in ajax calls.
Whilst it's not entirely clear from the jQuery.ajax documentation, this function returns a jqXHR object which implements the promise interface. So this means you can use the promise methods done, always and fail.
http://api.jquery.com/jQuery.ajax/

jquery trouble with getJSON call

Got some basic problem again.
I need to modify a function that previously returned a in code written object.
Im now trying to get the object from json through $.getJSON
function getEventData() {
var result = '';
$.getJSON("ajax.php?cmd=getbydate&fromdate=&todate=", function(data) {
result = data;
});
return result;
}
Problem is that result isn't set in the callback function for obvious reasons.
Do you guys have a solution for this?
Edit:
Ok i got an answer that was removed.
I just had to change it abit..
This is the answer that works:
function getEventData() {
var result = '';
url = "ajax.php?cmd=getbydate&fromdate=&todate=";
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function(data) {
result = data;
}
});
return result;
}
You should program your application in an asynchronous way, which means, that you should use callback functions for you application flow, too, or continue in the getJson callback function. You can also make the request synchronously which should then be able to return the value (or at least assign it and block the function till the callback is completed), but this is not recommended at all:
function getEventData() {
var result = '';
result = $.ajax({
url: "ajax.php?cmd=getbydate&fromdate=&todate=",
async: false,
dataType: "json",
data: data,
success: function(data) {
return data;
}
});
return result;
}
Are you sure that the server returns valid json? It will be better to validate it using a tool like jsonlint. Also make sure that application/json is used as content type for the response.

Using Jquery to get JSON objects from local file

I'm trying to get a list of JSON objects (products) from a local file using Jquery and store all the objects in a single array called allItems. The file is co-located in the same directory as the code, and it's called "allItems.json". Here's how I'm doing it now:
function getAllSupportedItems(){
var allItems = new Array();
$.getJSON("allItems.json",
function(data){
$.each(data.items,
function(item){
allItems.push(item);
});
});
return allItems;
}
Based on this example: http://api.jquery.com/jQuery.getJSON/
For getAllSupportedItems to be able to return any items, the AJAX call needs to run synchronously.
getJSON translates to the following asynchronous call:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback
});
Asynchronous is the default. You therefore need to explicitly change your request to a synchronous one:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback,
async: false
});
An alternative is to rethink the way you use getAllSupportedItems and make it into an asynchronous utility:
function getAllSupportedItems(callback){
$.getJSON("allItems.json",
function(data){
var allItems = [];
$.each(data.items,
function(item){
allItems.push(item);
});
callback(allItems);
// callback(data.items); should also work
});
}
Update
When I initially wrote this answer, jQuery didn't have built-in Deferred support. It is a lot more concise and flexible to do something like this today:
function getAllSupportedItems( ) {
return $.getJSON("allItems.json").then(function (data) {
return data.items;
});
}
// Usage:
getAllSupportedItems().done(function (items) {
// you have your items here
});
How are you using this? If you're expecting the main function ("getAllSupportedItems") to return the array you make, well that won't work. The $.getJSON function is asynchronous, and so the handler won't actually build the array until after the outer function has returned.

Categories

Resources