I have written a WCF service and am trying to call the service methods in a script in my ASPX page.
Eg:
<script language="javascript" type="text/javascript">
<!--
function Test() {
**// The following call is an Async call.
tempuri.org.IService.GetData(1,OnRequestComplete, OnError, "");**
}
function OnRequestComplete(result, state) {
var textBox = $get("txtInput");
textBox.value = result;
}
function OnError(result) {
var textBox = $get("txtInput");
textBox.value = result;
}
//-->
</script>
What I want is to be able to call the service method "synchronously"
eg: var result = tempuri.org.IService.GetData(1);
Is this possible?
I believe there's no ability to do synchronous calls in Javascript - the AJAX libraries will always return while waiting for a remote response.
Can you explain why you want to do this?
Edit:
In answer, you should use this method:
In the onclick event handler for your form submit button: Make the webservice validation call, and immediately return false (so the form does not submit). It would be a good idea to display to the user a 'Validating' type message, so they know what is happening here.
If you get a valid response, then use document.form.submit(); to submit the form to the server.
If you get an invalid response, or a server error, then display to the user a message to that effect.
If you use regular AJAX you can make your call synchronous.
See: http://www.w3schools.com/Ajax/ajax_xmlhttprequest_send.asp
and scroll down to the part "Asynchronous - True or False?"
Here I use AJAX but sometimes it hangs
www.DomainGuarder.com
Related
Suppose I have a page called form.php. I then clicked a button called "add button". This button triggers an event that got detected by a jquery function. The jquery function makes an ajax call to add.php.
Inside add.php, there is code that checks if a particular record exist in the database. If it does find that the record exists, I want to do the following.
Send a response string "exist" to ajax.
The ajax, inside the .done() function, will execute a prompt that says "This record already exist, do you wish to overright"?
If the user canceled the prompt, nothing more should happened and the ajax call should be done.
If the user clicks "ok", I would like the php script to be notified of this and execute an update statement using the data from form.php.
I suspect this is impossible because after receiving a response from php, AFAIK there is no way for ajax to respond back to the php script that is currently executing.
Am I correct or there is a way to do this?
You have to add a parameter to your ajax request, like override with true and false. By default/first request you set it to false. Then the add.php does it's default and returns exists.
The the user makes his decision. If he want to override, you send the ajax request again with the override parameter to true. Your add.php will notice the parameter and does whatever it has to do.
Wrap your ajax handler in an own function with a done callback. So you can reuse the request as often as you want. Pretty easy, no double code needed as well ...
The .done() function of your first ajax call executes when the ajax call has finished successfully, so when your php script has finished completely.
If you want to do something else, you would need to make a new ajax request. That could be to the same or another script, sending in different / new / additional parameters.
Note that you have to make sure that the second script cannot be called without the first one finishing, for example by setting and checking an expiring session variable.
you can do something like this.
$.post('add.php',$(this).serialize())
.done(function(result){
var r = confirm("This record already exist, do you wish to overright");
if(result == 'exist'){
if (r == true) {
$.post('update.php',$(this).serialize()).done(function(r){
console.log(r);
});
} else {
return false;
}
}else{
console.log(result)
}
});
I'm having numerous AJAX call using JQuery. Among these is an AJAX call, let's say auth() that checks whether the user is currently logged to the system, idle, etc, and if not, will cause the page to redirect to the login page.
This auth() function is called every minute. Other than that usage, I want to call this function on before every other AJAX call that will be made— just to ensure that they are logged to perform a transaction.
I'm thinking of using the beforeSend property of $.ajaxSetup to achieve this, but won't it also be attached to auth() since it is also an AJAX call? I can confirmed this because I have tried using beforeSend and it throws an error:
RangeError: Maximum call stack size exceeded
How can I select all AJAX call (except for auth()) and attach it an "onBeforeCall" listener?
You could overload the ajax method of jQuery:
var $ajax = $.ajax; // save old ajax method
$.ajax = function () {
if (!auth())
throw 'NOT AUTHENTIFICATED!'; // or whatever
return $ajax.apply(this, arguments); // if auth() passed call the old ajax method and return it so the whole jQuery API works...
);
The best way to do is to write a generic function which will act as a proxy to all of your AJAX calls. Something like this:
var ajax = {
send: function(url,type,success,error,data){
$.ajax{
url:url,
method:type,
beforeSend: function(xhr, opts){
if(!auth()) {
xhr.abort();
}
}
success:success,
error:error
}
}
}
Call all of your AJAX calls this way:
ajax.send(url,type,success,error,data); //Pass success and error as functions
In asp.net website, i need to submit the some fields to insert into database. OnclientClick event i have javascript method to validate the input, it method return false in case validation failed and true in case validation success. If it return true then server side event process ahead to insert the data.
My problem is in javascript main validation method it call server side method through ajax to get some data in order to validate the form. Main javascript method dont wait of server side call and it process move ahead, that means i am not able to validate that method and it go ahead and make postback.
function ValidateInput()
{
if(1 == 2)
{
return false;
}
// other logic to validate
ServiceSideCalltoValidate();
// It dont wait of above method and make the postback
}
In other words i need to implement the logic so that 1 javascript method should wait to finish the call of another javascript.
Your javascript function calls AJAX to validate the data and every AJAX call complete then it will return value. So what you need to do it, return some value from AJAX call and if its true then after you can call server size click event.
I am trying to figure out how to accomplish the following:
Handle client-side click event of button - prevent postback if result of javascript call is false (e.g. onclick="js:return IsThisAllowed()")
Javascript method will return true or false, depending on result of call to generated web service method using ScriptManagerProxy
The code below is simplified down to the main components that I am referring to in this question. I can alert() the return value no problem, but the part I'm having trouble with is how I can return the result of the web service method call back to the button onclick handler? Since the function Finish() is called in a separate thread upon success of what I assume is the XmlHttp.send() call, how can I send the value of the response as the return value of the javascript method? Am I going about this all wrong?
I've used similar code many times before to update the DOM with the return values, such as within a <div>, but never had to worry about capturing the return value and using it within my script.
What I have so far:
.NET web service method (VB.NET):
<WebMethod()> _
<ScriptMethod()> _
Public Function IsAllowed() As Boolean
Return True
End Function
.NET code for the page to generate AJAX web service methods, and html button
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Services>
<asp:ServiceReference Path="~/WebServices/MyWebService.asmx" />
</Services>
</asp:ScriptManagerProxy>
<asp:Button ID="_btn" runat="server" OnClientClick="js:return IsAllowed();" />
Javascript
<script type="text/javascript">
function IsAllowed(orderid) {
if (!processing) {
processing = true;
var ws = new MyWebService();
ws.IsAllowed(Finish, Error)
// return TRUE if call to IsAllowed returns true!!!
return false;
}
}
function Finish(result) {
alert(result)
}
function Error() {
}
</script>
You can't do this: the call to the web service is an asynchronous request to the server that immediately returns control to the client - and your javascript is (almost) always going to finish executing before the request completes (most likely before the request is even delivered).
Since you don't know when you'll receive the response from the call to ws.IsAllowed, you need to handle it in your callbacks (Finish and Error).
(This is true whatever AJAX mechanism you're using.)
I'm not familiar enough with ScriptManager-based AJAX to tell you exactly how to do this, but the general idea is that I'd turn it around: instead of canceling an ASP.NET button's click event, I'd only trigger the ASP.NET button if the AJAX call returned true.
Using jQuery, I'd do it by making the AJAX call from a vanilla HTML button (not an ASP.NET web control). In the success handler (the equivalent of Finish), I'd trigger my ASP.NET button (which I'd probably hide) when the return value is true.
Have you considered using jQuery?
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "~/WebServices/IsAllowed.asmx/{Method Name}",
data: ('{ whatever data is needed for decision making json serialized }'),
success: function (msg) {
alert(msg);
},
error: function (request, status, error) {
alert(err.Message);
alert(err.StackTrace);
}
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I'm using the ajax technique in combination with php and I want to know how to get the return variable from the function that is called by onreadstatechange.
A java function is called onsubmit to then call a php script to verify some things in my database and return true or false depending on the results.
Here is where I run into problems, I want the onsubmit="return snappyajaxfunction()" to return false or true based on the results from the php.
My question is, how do I get the result of false or true from the stateChanged function to become the return for snappyajaxfunction.
I tried doing this for kicks: result = request.onreadystatechange=StateChanged with no luck.
I've also tried saving the responsetxt to a global variable then returning the global variable in snappyajaxfunction with no luck.
snappyajaxfunction()
{
request.onreadystatechange=stateChanged;
request.open("GET",url,true);
request.send(null);
return result;
}
function stateChanged()
{
if (request.readyState==4)
{
return request.responseText;
}
}
The purpose of this is to script is to verify the username / password entered by the user with the username / password stored in my database. If it they don't match it returns false and the form will not submit, if it does the form submits and the user is brought to the welcome page...
You could do:
function stateChanged()
{
if (request.readyState==4)
{
OnStateChanged(request.responseText);
}
}
Where OnStateChanged is a function that act as an event handler...
EDIT: in OnStateChanged you can then submit or not your form based on response
EDIT2: On the server when you check the u/p, if they're right log the user right on and return the status to JavaScript.. then in the JavaScript instead of resubmitting a form, just reload/redirect the page if it is successful or display an alert otherwise...
It is just not possible to return something from a function by an asynchronous operation in it... the original thread of execution is long gone. The asynchronous operation is executed by another thread (If I remember correctly, don't flame).
Thanks
jQuery won't automagically fix the fact that he's trying to base his submission on the results of an asynchronous request.
What you can do is the following:
1) Set the form onsubmit to simply call snappyajaxfunction();
2) In stateChanged, if the readystate is 4, obtain a reference to the form and do the following:
form.onsubmit = function() { return true; };
form.submit();
Basically - Set the onsubmit to always return true and then force it to submit again. For added usability you may want to disable the button causing the submission while waiting for statechanged to happen. And then re-enable it.
feel free to check out this tutorial on ajax.
It will show you how to properly use ajax step-by-step
as inkedmn has suggested, I would recommend using jquery or any of the other js frameworks
The problem is that ajax calls are asynchronous. That means the response is separate from the request. You have to modify your code to handle that. You cannot (should not) make http calls synchronous.
Look at this code. It works, and you'll be able to read the response:
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (ev) {
if (req.readyState == 4) {
alert(req.responseText);
}
};
req.send(null);
To make your code work you can use closures and pass functions as parameters.2 properties javascript is very good at.
snappyajaxfunction(url, fn)
{
var request...
request.onreadystatechange=function()
{
if (request.readyState==4)
{
fn(request.responseText);
}
};
request.open("GET",url,true);
request.send(null);
}
to use it you can build a function like
var doSomething = function(response){
alert(response);
};
snappyajaxfunction('/country/code/32', doSomething);
The closure allows 'request' to be available within the function that handles the onreadystatechange.
The function 'fn' is passed as a parameter of snappyajaxfunction.