JQuery ajax calls collision using Play! framework - ajax

When some action is invoked in my page, I make two ajax calls (A, B) to two different methods on my server.
Most of the times each request gets its matching response, but here and there both requests gets the same response! (of one of the requests - A,A or B,B)
The Ajax calls are made using JQuery and the server methods are implemented using Play! framework (in java).
Does anyone have any idea why does it happen and how to resolve it?
Thanks!
Ajax Call A:
var renderTypePreviewPageRoute = jsRoutes.com.eyeview.connectad.controllers.solutions.FeedLibrary.getFeedTypePreviewPage(feedHashId, feedType);
// Makes an ajax call that gets the rendered solution page
$.ajax({
// Sets the route (URL) of the server call
url:renderTypePreviewPageRoute.url,
// Sets the method (GET / POST) of the server call
type:renderTypePreviewPageRoute.method,
//data:{ hashId: feedHashId, feedType: feedType, withPreview: withPreview }-->
// In case of success
success:function(result) {
var typePreviewElement = $('#typePreviewSection');
// Set the feed preview section html content to the rendered content got from the server
typePreviewElement.html(result);
typePreviewElement.removeClass('hidden');
$('#feedPreviewGrid tr:eq(1)').removeClass('hidden');
if ($('#feedPreviewSection').is(':visible')){
typePreviewElement.show('blind');
}
var feedURL = urlEle.val();
if (waitForFileTypePreview && feedURL != "") {
feedEditNS.renderFilePreviewSection(true);
}
},
// In case of failure
error:function(xhr, ajaxOptions, thrownError) {
// Shows the error message
showError(xhr.responseText);
// Clears the preview section
feedEditNS.clearTypePreviewSection();
var feedURL = urlEle.val();
if (waitForFileTypePreview && feedURL != "") {
feedEditNS.renderFilePreviewSection(true);
}
}
Ajax Call B:
var renderFilePreviewPageRoute = jsRoutes.com.eyeview.connectad.controllers.solutions.FeedLibrary.getFeedFilePreviewPage(feedHashId);
// Makes an ajax call that gets the rendered solution page
$.ajax({
// Sets the route (URL) of the server call
url:renderFilePreviewPageRoute.url,
// Sets the method (GET / POST) of the server call
type:renderFilePreviewPageRoute.method,
// In case of success
success:function(result) {
// Set the feed preview section html content to the rendered content got from the server
$('#filePreviewSection').html(result);
// Shows the feed preview section
$('#verticalLine').show('blind');
$('#leftShadow').show('blind');
$('#rightShadow').show('blind');
$('#feedPreviewSection').show('blind');
feedEditNS.createDataTable(withHeaders);
waitForFileTypePreview = false;
},
// In case of failure
error:function(xhr, ajaxOptions, thrownError) {
// Shows the error message
showError(xhr.responseText);
// Clears the preview section
feedEditNS.clearFilePreviewSection();
waitForFileTypePreview = false;
}

I could not resolve the problem.
So, I ended up combining both calls to one call to a single server side method.
This method returned a JSON object containing both calls answers.

I ran into this exact issue (3'ish years later...) I am still not sure what the real problem is, but as a workaround I ended up using setTimeout() inside my Angular controller.
myApp.controller('myCtrl', function($scope, myRestApi) {
$scope.restCallOne = function() {
myRestApi.callOne().then(
// handle result one
);
};
$scope.restCallTwo = function() {
myRestApi.callTwo().then(
// handle result two
);
};
// loads each time the view is shown
// *** race condition when calling consecutively without a delay ***
//$scope.restCallOne();
setTimeout($scope.restCallOne, 100);
$scope.restCallTwo();
});

Related

cannot click links contained within ajax response

I have some content returned via ajax, and that content contains some links, but if I click them nothing happens (they don't respond to the JS written for them). Then, If i refresh the page, the first time I click, it works, and then it doesn't again.
How can I make it work normally?
This is basically my ajax call:
$('a.add').click(function() {
var data = {
action: 'ADD_PROD'
};
// make the request
$.get(ajax_object.ajax_url, data, function(response) {
// $('#vru_div').html(data);
$('div.left').html(response);
});
// $('div.left').html('<img src=712.gif>');
// alert('code');
return false;
});
The new links won't have any event handlers attached to them.
try using
$('.left').on('click','a',function(){
//your logic
});

Angular JS data not populated from asynchronous http request

I am trying to get a loading div to show when my angular module is contacting the server. I am using AngularJS 1.0.1 and AngularJS Resources 1.0.1 to expand the functionality of the HTML and jquery 1.7.2 for some additional dom manipulation and ajax support.
I already found out that the loading div will not show if I run the ajax call in async false, except for Firefox where it shows but animated gif is not animated.
If I run the ajax call in async true, the data returned back does not get loaded into the angular model variables of the loaded template partial.
Is it at all possible to get an animated loading div to show and get the angular data to load into the model?
Hopefully I'm understanding you correctly. You want to show a loading progress for your ajax requests. To do this you need a response interceptor. Here is a an example of how to do this http://jsfiddle.net/zdam/dBR2r/
// register the interceptor as a service, intercepts ALL angular ajax http calls
.factory('myHttpInterceptor', function ($q, $window, $rootScope) {
return function (promise) {
$rootScope.nowloading = true; // use ng-show="nowloading" on element containing spinner
return promise.then(function (response) {
// do something on success
$rootScope.nowloading = false; // need to turn it off on success
return response;
}, function (response) {
// do something on error
$rootScope.nowloading = false; // need to turn it off on failure
$rootScope.network_error = true; // you might want to show an error icon.
return $q.reject(response);
});
};
hope this helps
--dan

jquery mobile ajax sends both GET and POST requests

Here is the problem:
By default jQuery Mobile is using GET requests for all links in the application, so I got this small script to remove it from each link.
$('a').each(function () {
$(this).attr("data-ajax", "false");
});
But I have a pager in which I actually want to use AJAX. The pager link uses HttpPost request for a controller action. So I commented the above jQuery code so that I can actually use AJAX.
The problem is that when I click on the link there are two requests sent out, one is HttpGet - which is the jQuery Mobile AJAX default (which I don't want), and the second one is the HttpPost that I actually want to work. When I have the above jQuery code working, AJAX is turned off completely and it just goes to the URL and reloads the window.
I am using asp.net MVC 3. Thank you
Instead of disabling AJAX-linking, you can hijack clicks on the links and decide whether or not to use $.post():
$(document).delegate('a', 'click', function (event) {
//prevent the default click behavior from occuring
event.preventDefault();
//cache this link and it's href attribute
var $this = $(this),
href = $this.attr('href');
//check to see if this link has the `ajax-post` class
if ($this.hasClass('ajax-post')) {
//split the href attribute by the question mark to get just the query string, then iterate over all the key => value pairs and add them to an object to be added to the `$.post` request
var data = {};
if (href.indexOf('?') > -1) {
var tmp = href.split('?')[1].split('&'),
itmp = [];
for (var i = 0, len = tmp.length; i < len; i++) {
itmp = tmp[i].split('=');
data.[itmp[0]] = itmp[1];
}
}
//send POST request and show loading message
$.mobile.showPageLoadingMsg();
$.post(href, data, function (serverResponse) {
//append the server response to the `body` element (assuming your server-side script is outputting the proper HTML to append to the `body` element)
$('body').append(serverResponse);
//now change to the newly added page and remove the loading message
$.mobile.changePage($('#page-id'));
$.mobile.hidePageLoadingMsg();
});
} else {
$.mobile.changePage(href);
}
});
The above code expects you to add the ajax-post class to any link you want to use the $.post() method.
On a general note, event.preventDefault() is useful to stop any other handling of an event so you can do what you want with the event. If you use event.preventDefault() you must declare event as an argument for the function it's in.
Also .each() isn't necessary in your code:
$('a').attr("data-ajax", "false");
will work just fine.
You can also turn off AJAX-linking globally by binding to the mobileinit event like this:
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Source: http://jquerymobile.com/demos/1.0/docs/api/globalconfig.html

Can't get form to submit after successful AJAX validation with PHP and Prototype

I have forms on a site that are processed by PHP, including validation. Normally, if there's errors, the user is returned to the form with the appropriate error messages. For users with javascript enabled, I'm trying to write a javascript with Prototype that uses AJAX to do the same PHP validation (to avoid code duplication) and display the error messages without having to actually submit the form and wait for it to reload.
The script works very well at grabbing the errors via AJAX and displaying them. But, when there are no errors, I cannot get the form to submit and move forward to the next page. I've been working with Event.stopObserving, but it just reloads the page (which is not the form action url, the form submits to a different page than the form itself, so it's not the server sending the browser back). I'm not that good with javascript and Prototype, so I'm probably missing something obvious, but any help would be greatly appreciated. Anyway, here is my code:
document.observe("dom:loaded", function() {
$$('form')[0].observe('submit', validate);
function validate(event) {
event.stop();
// remove any existing error messages
var curErrors = $$('ul.error');
for( i=0, im=curErrors.length; i<im; i++ ) curErrors[i].remove();
$$('form')[0].request({
parameters: { 'js' : 1 },
requestHeaders: {Accept: 'application/json'},
onSuccess: function(req) {
var errors = req.responseText;
if( errors == '[]' ) {
// no errors, submit form to server
$$('form')[0].stopObserving('submit', validate);
$$('form')[0].submit();
} else {
// have errors, display error messages
var errors = errors.evalJSON(true);
for( var error in errors ) {
var errorMsg = '<ul class="error"><li>' + errors[error] + '</li></ul>';
var input = $$('[name="'+error+'"]')[0];
// display error message next to form field
. . .
}
}
},
onFailure: function() {
// can't validate here, let server do it
$$('form')[0].stopObserving('submit', validate);
$$('form')[0].submit();
}
});
}
});
Don't call event.stop() immediately within your validate method - the event handler will occur before the event does, meaning that the validate method will run before the form is submitted. Simply move that line within the branch of the if statement regarding validation failure, and it ought to work just fine.
http://www.prototypejs.org/api/event/stop

Ajax Broken in Browsers works in Android

I can run this code in Android app (using PhoneGap adn jQuery Mobile) but not on desktop browsers.
It gives me a syntax error in firebug for this line =
var TicketList = eval("(" + ajax.responseText + ")");
Here is the code
// JScript source code
// ran on body load
function doJsStuff()
{
var ajax = AJAX();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4) {
var TicketList = eval("(" + ajax.responseText + ")");
if (TicketList.ListCount > 0) {
document.getElementById("opencount").innerHTML = TicketList.ListCount +" Open Tickets";
for (Ticket in TicketList.Tickets) {
// add stuff to DOM
//AddTicketToList(TicketList.Tickets[Ticket]);
}
}
else {
document.getElementById("opencount").innerHTML = "All Tickets Reviewed";
DisplayNoresults();
}
}
}
ajax.open("GET", "http://website.com/ListTicketsRequest.ashx?PageNumber=1&PageSize=1&Status=Open", true);
ajax.send(null);
//document.addEventListener("deviceready", onDeviceReady, false);
//event to check for PhoneGap
//$('ul').listview('refresh');
$('#mtickets').page();
//showVars();
}
function AJAX()
{
var xmlHttp;
try
{
xmlHttp = new XMLHttpRequest();
}
catch (e)
{
}
return xmlHttp;
}
**TicketList is a variable in the JSon that comes across like this=
{"Tickets" : [{"TicketID": "1054","Category": "N/A","SubmittedUserID": "bob.thebuilder","ShortDescription": "test question QID:16668","CreationDate": "2/16/2011 12:24:19 PM","TicketStatus": "Open","LongDescription": "Something is wrong with this question I know I hve the right answer but it keeps telling me I'm wrong"},{"TicketID": "1053","Category": "Mission Support","SubmittedUserID": "dave","ShortDescription": "Make courseware revisions","CreationDate": "2/16/2011 9:34:48 AM","TicketStatus": "Open","LongDescription": "Find help tickets generated by users for possible courseware update."}], "PageCount": "6", "ListCount": "11"}
Note about PhoneGap If you are trying to include phoengap functions in a place where the code may also be executed on in a browser make sure you only add the phone gap function with on "deviceready" or your browser will not render. Example:
function onload(){
//event to check for PhoneGap
document.addEventListener("deviceready", onDeviceReady, true);
}
...
function onDeviceReady()
{
// Now PhoneGap API ready
vibrate(90); // vib to ack pg ready
$("a").click(function(event){
vibrate(30); // add 30 sec vib to all links
});
}
My immediate response would be to use jQuery's getJSON method, since you're aready using jQuery. jQuery's AJAX provides a much broader base of browser compatibility. Also, every time you use eval(), a small baby somewhere cries.
var url = "http://website.com/ListTicketsRequest.ashx?PageNumber=1&PageSize=1&Status=Open";
$.getJSON(url ,function(TicketList){
if (TicketList.ListCount > 0) {
$("#opencount").html(TicketList.ListCount +" Open Tickets");
for (Ticket in TicketList.Tickets) {
...
}
} else {
$("#opencount").html("All Tickets Reviewed");
DisplayNoresults();
}
});
If this still doesn't work for you, ensure that the JSON being returned is valid. But please stick to this method, and don't use eval!!
SIMPLIFIED UPDATE
var url = "http://website.com/ListTicketsRequest.ashx?PageNumber=1&PageSize=1&Status=Open";
$.getJSON(url ,function(AnyNameYouWant){
alert(AnyNameYouWant.ListCount + " Open Tickets");
});
UPDATE USING 'DATA'
If your url becomes too long, you might begin to encounter problems. It is suggested to pass the url data via the data argument.
var url = "http://website.com/ListTicketsRequest.ashx";
var data = "PageNumber=1&PageSize=1&Status=Open";
$.getJSON(url, data, function(AnyNameYouWant){
alert(AnyNameYouWant.ListCount + " Open Tickets");
});
Looking at your code, it seems likely to me that the syntax error isn't in the code you posted, but instead is contained in the JSON object you're evaluating in ajax.responseText. Take a look at the data being returned by the AJAX request. Is it valid Javascript? Does the page you're calling return something different to desktop browsers vs mobile? Is there an error message where the JSON code should be?
Another possibility: Is your app running on website.com? If not, Firefox is probably blocking the XMLHttpRequest from functioning properly. Firefox 3 and below block cross-site AJAX requests. Firefox 3.5 seems to allow some exceptions.

Resources