jQuery cannot get a success function working - javascript

I am having trouble getting a success: function(){} working - the ajax code I am using is this:
jQuery.ajax({
url: 'http://127.0.1/process_form.php'+data,
data: data,
dataType: "jsonp",
jsonp : "callback",
jsonpCallback: "jsonpcallback"
});
data is a simple string and is being passed by jsonp as when complete will pass data cross domains. I know about security with a GET and that Curl would be better, but this is a simple "predefined" string with no user input. The data is just the text from one of 4 links. i.e. "yes" "No" "Don't know" "made this one up" There is actually no need for a form either.
I get all the "data" into the DB but what I can't get to happen is the "next" bit based on the success. If I do a simple success: function(){} nothing happens (with that function) regardless of "what" e.g. an alert etc.
What should (and does of sorts) happen is the data is posted to the DB, a jQuery.getJSON statement then queries the DB and prints out ALL the data i.e. all entered rows, not just the last.
When I say "sort of works" the jQuery.getJSON returns the data, but sometimes "misses" doing it until the next time data is sent. It seems to me all to do with timing because if I wrap the "print" function inside a setInterval() the whole thing works fine. Just I don't really need the setInterval to contunually work.
For example:
jQuery('.addinput').live('click',function(){
var fldID = new Date().getTime();
var fldType = jQuery(this).html().toLowerCase();
var data ='';
data += '?fldID='+fldID;
data += '&fldType='+fldType;
data += iptime;
jQuery.ajax({
url: 'http://127.0.1/process_form.php'+data,
data: data,
dataType: "jsonp",
jsonp : "callback",
jsonpCallback: "jsonpcallback"
});
jQuery('.loader').fadeIn('slow');
setInterval(function() { fn_form(iptime); }, 3000 );
jQuery('.loader').fadeOut('slow');
return true;
});
This works OK but I really don't want the fn_form(iptime) function to be continually refreshed.
What I'd rather see is something like this:
jQuery('.addinput').live('click',function(){
var fldID = new Date().getTime();
var fldType = jQuery(this).html().toLowerCase();
var data ='';
data += '?fldID='+fldID;
data += '&fldType='+fldType;
data += iptime;
jQuery.ajax({
url: 'http://127.0.1/process_form.php'+data,
data: data,
dataType: "jsonp",
jsonp : "callback",
jsonpCallback: "jsonpcallback",
success: function(){
// run fn_form(iptime)
}
});

You can use this alternative solution to jQuery's implementation of JSONP which simplify JSONP calls.
jQuery-JSONP features:
1- error recovery in case of network failure or ill-formed JSON responses,
2- precise control over callback naming and how it is transmitted in the URL,
3- multiple requests with the same callback name running concurrently,
4- two caching mechanisms (browser-based and page based),
5- the possibility to manually abort the request just like any other AJAX request,
a timeout mechanism.

Related

How to run getJSON synchronously? [duplicate]

GOAL: What I'm after is to get data from database and refresh main.php (more evident through draw_polygon) every time something is added in database (after $.ajax to submit_to_db.php).
So basically I have a main.php that will ajax call another php to receive an array that will be saved to database, and a json call another php to return an array will be used by main.php.
$(document).ready(function() {
get_from_db();
$('#button_cancel').click(function(){
$.ajax({
url: 'submit_to_db.php',
type: 'POST',
data: {list_item: selected_from_list},
success: function(result){
...
get_from_db();
}
});
});
function get_from_db(){
$.getJSON('get_from_db.php', function(data) {
...
draw_polygon(data);
});
}
});
In my case, what I did was a get_from_db function call for getJSON to actually get data from database, with the data to be used to draw_polygon. But is that how it should be done? I'm a complete newbie and this is my first time to try getJSON and ajax too to be honest. So my question: How does asynchronous work actually? Is there another workaround for this instead of having to call function get_from_db with getJSON (it isn't synchronous, is it? is that why it doesn't update the page when it isn't within a function?) All the time - like $.ajax with async: false (I couldn't get it to work by the way). My approach is working, but I thought maybe there are other better ways to do it. I'd love to learn how.
To make it more clearer, here's what I want to achieve:
#start of page, get data from database (currently through getJSON)
Paint or draw in canvas using the data
When I click the done button it will update the database
I want to AUTOMATICALLY get the data again to repaint the changes in canvas.
Since $.getJSON() uses ajax configurations, just set the global ajax configs:
// Set the global configs to synchronous
$.ajaxSetup({
async: false
});
// Your $.getJSON() request is now synchronous...
// Set the global configs back to asynchronous
$.ajaxSetup({
async: true
});
Asynchronusly does mean the Request is running in the background, and calls your function back when it got a response. This method is best if you want to have a result but allow to use your app within the request. If you want to have a direct response, take a look at a synchron request. this request will pause script execution until it got a response, and the user can not do anything until the response was recieved. You can toggle it via:
async: false,
So for example:
$.ajax({
url: "myurl",
async: false,
...
})
$.getJSON(), doesn't accept a configuration, as it says in the docs it's a shorthand version of:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
So just rewrite your request in terms of that and async:false will work just as you expect.
$.getJSON() is a shorthand notation for $.ajax() which can be configured to be synchronous (see jQuery.getJSON and JQuery.ajax):
$.ajax({
dataType: "json",
url: url,
data: data,
async: false,
success: function(data) {
...
draw_polygon(data);
}
});
Try to avoid synchronous calls though. Quote from jQuery doc (see async prop):
Cross-domain requests and dataType: "jsonp" requests do not support
synchronous operation. Note that synchronous requests may temporarily
lock the browser, disabling any actions while the request is active.
You might want to try jQuery Deferreds like this:
var jqxhr = $.getJSON(url);
jqxhr.done(function(data) {
...
draw_polygon(data);
});

Asynchronous Lazy Loading

currently, we are using the SAP HANA Database. To get data, we will use a Node.JS-API, which we will call via AJAX, to get the advantages by async. So here is the problem:
We have many pages where we need the same data (e.g. customer data). To do so, I wanted to create a Library, which does the actual data calls, so that i just need to call db.getCustomer([ID]). In order to get a return value from AJAX, I have to set async: false within the AJAX call.
My question is now, is it possible to create a data-call-library asynchronously? Is it a good practice to encapsulate the databinding (using so called DAO)?
I'm a bit confused, because another dev told me to just use the same AJAX-call over and over again, to not loose the async and it is a better practice anyway.
Here is my actual AJAX-call as an example:
getCustomer: function( CID ) {
var aUrl = 'http://example.com/api/customer/' + CID,
returnData
;
jQuery.ajax({
url: aUrl,
method: 'GET',
dataType: 'json',
contentType: "application/json",
async: false,
success: function(data) {
returnData = data;
}
});
return returnData;
},
// other ajax calls
// to get the data via 1-liner
thank you for clarification!
Actually, it makes no sense to return data from a callback in a synchronous function; normally, you would store the returned callback data into your model, so your view/controller gets automatically updated.
If you really need your method to return async data, have a look at Deferred or Promises

Multiple jQuery Ajax calls in a Backbone App mixes data up

I work on a Backbone app with a collection for data sources. Whenever a new data source is added, its model is added to the collection, and a jQuery Ajax call is made for it like this:
fetch: function() {
var model = this,
url = model.get("url");
function testCallback(parObj) {
return function(data, textStatus, jqXHR) {
alert("test - "+parObj.url+" : "+data.sourceurl);
}
}
$.ajax({
url: url,
type: "GET",
dataType: "jsonp",
jsonpCallback: "data",
success: testCallback({ model: model, url: url })
})
.done(function (data) {
alert("done - "+model.get("url")+" : "+data.sourceurl);
});
}
The fetch() is called in rapid succession, and debugging it I can see everything is ok when I initiate the Ajax request.
Everything works great if I only add two data sources.
But both the done() and testCallBack() functions mixes up the data when I have three requests running simultaneously on three different domains (same happens in both Chrome and Safari).
For instance:
URL 1 gets the data from URL 1.
URL 2 gets the data from URL 3.
URL 3 gets the data from URL 2.
Am I doing something wrong? Any help is greatly appreciated.
That's because you're setting the jsonpCallback parameter to the same thing for each request. Just remove that line entirely as jQuery will automatically create unique ones for you.

Having problems with jQuery, ajax and jsonp

I am using jsonp and ajax to query a web-service written in java on another server. I am using the following jquery command:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "sites_return"
});
function jsonp_callback(data) {
console.log(data);
}
function sites_return(data) {
console.log(data);
}
So my problem is that after the query finishes a function called jsonp_callback is called. Where I can clearly see the json formatted string:
{"listEntries":["ELEM1", "ELEM2", "ELEM3", etc...]}
But after the function sites_return is called when the complete event fires, I get the the following:
Object { readyState=4, status=200, statusText="parsererror"}
Also for reference the jsonp_callback function is called before the sites_return function. Also if i take the jsonp_callback function out of the code, I get a complaint it firebug that the function is not implemented.
My question three fold:
1) What am i doing wrong on the jquery side?
2) Why does the json get parsed correctly in jsonp_callback but not sites_return?
3) What can i do to fix these issues?
EDIT
Some new development. Per the comments here is some additional information.
The following is what comes out of the http response
jsonp_callback({"listEntries":["ELEM1", "ELEM2", "ELEM3"]})
I assume this is the reason jsonp_callback is being called. I guess my question now becomes, is there any way to control this (assuming i don't have access to the back end web-service).
Hope this helps~
var url = "http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
var address = "1600+Amphitheatre+Parkway";
var apiKey = "+Mountain+View,+CA";
$.getJSON("http://maps.google.com/maps/geo?q="+ address+"&key="+apiKey+"&sensor=false&output=json&callback=?",
function(data, textStatus){
console.log(data);
});
I believe that the first argument to the sites_return function would be the jqXHR Object. Instead of complete try using success.
But still this may not work as it seems that there is a parsing error (mentioned in the return value of sites_return function called from oncomplete). Therefore, you would first need to check your json string.
To Validate JSON, you can use http://jsonlint.com/
I think that the problem is that your server is not behaving the way jQuery expects it to. The JSONP "protocol" is not very stable, but generally what's supposed to happen is that the site should look for the "callback" parameter and use that as the function name when it builds the JSONP response. It looks as if your server always uses the function name "jsonp_callback".
It might work to tell jQuery that your callback is "jsonp_callback" directly:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "jsonp_callback"
});
Not 100% sure however.
If you don't have the ability to change the JSONP function wrapper that the remote server returns, jQuery's $.ajax() may be overkill here. Ultimately, all you're doing is injecting a script reference to wsUrl, which makes a call to jsonp_callback with a JavaScript object literal as its input parameter.
You could just as easily do something like this and avoid the confusion around the callback naming/syntax:
$.getScript(wsUrl);
function jsonp_callback(response) {
// Access the array here via response.listEntries
}

How to download a text file and store as a string in jQuery

I have a set of text files representing a table of data from a third party that I'd like to download using a JavaScript application. They look something like this:
col1 col2 .. coln
vala valb .. valz
valA valB .. valZ
etc..
I've been trying to use jQuery to do this. I've been able to use $.load, but I don't want to store the data in the DOM, instead I'd like to parse it out into an object. Whenever I try to use an of the ajaxy methods I'm getting an error I don't understand. For example:
var myData;
$.ajax({
type: 'GET',
url: $(this).attr('source'),
dataType: 'html',
success: function(data) {
myData = data;
}
});
alert(myData);
Gives me an undefined value for myData. Any suggestions would be appreciated.
For that code to work the event needs to be syncrounus, in other word, set async: false in the $.ajax-call. The problem comes because ajax is normally async, meaning that when you do the alert, the request might, or might not have finished. Normally though, it won't cause it takes longer time to fetch a page than to do a function-call. So, by setting async: false, you tell jquery (and the ajax-handler) to wait till the page is finished loaded before you try to alert the data. Another method to achieve the same effect is to do something like this:
var myData;
function fin(data) {
myData = data;
alert(myData);
}
$.ajax({
type: 'GET',
url: $(this).attr('source'),
dataType: 'html',
success: fin
});
This approach is probably better than to set async to false, because it won't make the browser hang while waiting for the page your loading. However, asynchronous programming is not something that is easy to learn, therefore many will find it easier to use async: false.

Categories