Calling Javascript After Web Method has fired - asp.net

I'm trying to implement the cascading dropdown from the toolkit. I need to get the count in a sub category dropdown, if it's zero then I turn off the visibility of the sub category.
If I use the javascript OnChange event then my script fires before the web method, so I need to know how to fire my script AFTER the web method has fired please.
My demo page: http://bit.ly/92RYvq
Below is my code and the order I need it to fire.
[WebMethod]
public CascadingDropDownNameValue[] GetSubCats1(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
int CategoryID;
if (!kv.ContainsKey("Category") || !Int32.TryParse(kv["Category"], out CategoryID))
{
return null;
}
dsSubCat1TableAdapters.Categories_Sub1TableAdapter SubCats1Adapter = new dsSubCat1TableAdapters.Categories_Sub1TableAdapter();
dsSubCat1.Categories_Sub1DataTable SubCats1 = SubCats1Adapter.GetSubCats1(CategoryID);
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
foreach (DataRow dr in SubCats1)
{
values.Add(new CascadingDropDownNameValue((string)dr["SubCategory1"], dr["SubCatID1"].ToString()));
}
return values.ToArray();
}
function getSubCatCount() {
$get("ddlSubCats1").style.display = $get("ddlSubCats1").length > 1 ? "block" : "none";
}

Generally when you call your web method function through javascript you can supply it two call back functions. One gets fired if there is an error and the other gets fire once the web method call has been completed. The callback requires two arguments, the result and a context. For example if your function was called myWebMethodFunction and your namespace it was contained in was my.fully.qualified.namespace it may look like this.
my.fully.qualified.namespace.myWebMethodFunction(param1, param2, ... , paramN, onErrorCallback, onCompleteCallback, context);
Once that function finishes, it will call the onCompleteCallback passing the result of your webmethod function and whatever you passed for a context.
It has been a while since I've called a web method function so I might have gotten the order of the callback reversed.
For some reason I can't comment on things either, but I can add to this.
I may be thinking about something different, but you must be calling something through javascript to fire your webmethod, correct? Whatever you use to call the webmethod through javascript should provide a mechanism to add a callback that will be fired once your webmethod call is complete and returned.

Use jQuery.ajax() it allows you to specify a success function and a failure function that fire after the web method returns.

Related

Calling Generic-HttpHandler inside another Generic-HttpHandler

I want to call a genric http-handler inside another generic-http-handler Inside the same project.
Suppose I have to two handlers
FirstHanlder.ashx
SecondHandler.ashx
I want to call the second on SecondHandler.ashx on the FirstHandler.ashx
I created an instance of SecondHandler.ashx on the FirstHandler.ashx as follows
var objCreateLogs=new SecondHandler();
objCreateLogs.ProcessRequest(context);
I want to know will it work?
1. Further more do I need to pass the `**context**` or it will be implicitly there.
How Can I get response of the SecondHandler.ashx on the FirstHandler.ashx since the return type of ProcessRequest is void.
Can I get response from httpcontex
Thanks.
The handlers should not do the work. Create a Class/Method that does the word and use it in both handlers.
//Extract parameters
string par1=Request["a"];
//...
//Call a backend function
var result = MyFunctions.DoTheWork(par1);

Flex Event Dispatching

I have some questions with a particular structure of a program I'm writing.
I'm using a Remote Object to make a remote call to a Rails method (using WebOrb). The problem arises in the way that I get my data back.
Basically I have a function, getConditions, in which I add an event listener to my remote call and then I make the remote call. However, what I want to do is to get that data back in getConditions so I can return it. This is a problem because I only access the event result data in the event handler. Here's some basic code describing this issue:
public function getConditions():Array
{
remoteObject.getConditions.addEventListener("result", onConditionResult);
remoteObject.getConditions();
//Here is where I want to get my event.result data back
}
public function onConditionResult(event:ResultEvent):void
{
//Here's the data that I want
event.result;
}
How can I achieve this data turn-about?
Remote calls in flex are always asynchronous so you won't be able to call getConditions() and wait there for the result. You have to use a function closure to process the results, either by means of an event handler than you declare elsewhere or a dynamic one created immediately within getConditions(), like so:
remoteObject.getConditions.addEventListener("result", function(event:ResultEvent):void {
// Run the code that you would want to when process the result.
});
remoteObject.getConditions();
The advantage of doing the above is that you would be able to "see" parameters passed to getConditions() or the result of any logic that happened before addEventListener() in the function closure. This however, takes a slight performance hit compared to declaring an explicit function (for that exact reason).
I should also add that doing so requires you to clean up after yourselves to make sure that you are not creating a new listener for every request.
you do it like this
public function getConditions():Array
{
remoteObject.getConditions.addEventListener("result", onConditionResult);
remoteObject.getConditions();
}
public function callMyExtraFunction(data:Object):void
{
//Here is where you want to get your event.result data back
}
public function onConditionResult(event:ResultEvent):void
{
//Here's the data that you want
var data:Object = event.result;
callMyExtraFunction(data);
}
You could make use of Call Responder like so :
<s:CallResponder id="getOperationsResult"/>
then use these lines to get the result from get operations
getOperationResult.token = remoteObject.getOperation();
this creates the call and returns the result stores it in getOpresult
whnever u want to access this u can call that token or getOperationResult.lastResult
Hope that helps
Chris

Flex RemoteObject Synchronous call

In the code below when I call chkAuthentication function from another function the remoteObj.login (login function in my service file (.php)) is called after the remaining code in that function. i.e., the loginStatus is returned from the function before the result-handler function loginResult is called. but my loginStatus is supposed to be set in loginResult function. It seems that the asynchronous behaviour is the culprit. what should I do in order to get the loginResult function to complete first?
Please help me out. Thank you.
private var loginStatus:Boolean;
public function chkAuthentication(loginVOObj:LoginVO):String{
remoteObj.login.addEventListener(ResultEvent.RESULT,loginResult);
remoteObj.login(loginVOObj);
if(loginStatus == true){
return displayName;
}
else{
return 'fail';
}
}
private function loginResult(result:ResultEvent):void
{
if(result.result == null){
loginStatus=false;
}else{
loginStatus=true;
}
}
The chkAuthentication method should not return a String since it is asynchronous. Instead, just create an instance variable and set its String value in the loginResult method. You can then use a binding or dispatch an event to update the UI.
The previous answer is correct - rather than depending on the service to act synchronously, which, aside from performance issues, is a rare case in flex, you should use the loginResult function to store the login status in this object or an object that you're using to store the application's state. Then, display it using a databound control:
<mx:label text={userStatus.loginDisplay} />

How does ASP.NET AJAX work when retrieving values from the server?

If I want to call a server function from JavaScript to retrieve a name of a person from a database (just as an example)... and I went...
name = myServices.getName(userId);
If I have a script manager with a service reference to a .asmx file that has the web method getName( int userId ) {} then this function should be called properly and would, eventually, return the name for that userId.
Unfortunately, I want to do...
name = myServices.getName(userId);
alert(name);
however, when doing ASP.NET AJAX, it would call the web method and continue executing before waiting for a response from the server (which I understand is the point of AJAX, to stop the browser from freezing while waiting for data)
I need to get the name back from the server before I can continue executing... How can I approach this to fix this issue?
There is a method you can add as a parameter to the service method that will call the method on success where you can do other stuff.
For example:
function test() {
PageMethods.MyMethod("name", OnMyMethodComplete);
}
function OnMyMethodComplete(result, userContext, methodName) {
alert(result);
}
If you want to call a Web method synchronously, you'll need to set up the request manually and use a Sys.Net.XMLHttpSyncExecutor.
Here's an example (see ExecuteSynchronously function).
For a JavaScript solution, you could loop until name has a value. Adjust time-based on latency to keep app responsive
var time = 100;
window.setTimeout(name == '' ? wait : continue, time);
function wait() {
window.setTimeout(name == '' ? wait : continue, time);
}
function continue() {
//code having to do with name
alert(name);
}
Congratulations! You've taken your first step into a larger asynchronous world. I'd definitely go with using the callbacks that CSharpAtl suggested.

ASP.Net ScriptControl - Add the Javascript get_events method : Possible?

So I've run into a snag, apparently the get_events method is only "included" with the ExtenderControl class.
What I need to do:
Be able to call the get_events Javascript method using a ScriptControl since using an ExtenderControl isn't really possible at this point.
I am hoping there is an easy way to have the scriptControl's javascript object inherit from something (If that's even possible).
Turns out the get_events method is really simple to create. You just need a field to hold a dictionary, a couple lines of code, and something to call the event if needed:
getEvents: function()
{
if (this._events == null)
{
this._events = new Sys.EventHandlerList();
}
return this._events;
},
And now for access:
onItemSelected: function(args)
{
this.raiseEvent('userItemSelected', args);
},
raiseEvent: function(eventName, eventArgs)
{
var handler = this.getEvents().getHandler(eventName);
if(handler)
{
handler(this._autoComplete, eventArgs);
}
},
Basically events is just a dictionary that holds the name of the event and the reference to the method to call. Once you have the method (handler), it's just a matter of calling it.

Resources