PDA

View Full Version : DWR calls and the return value



thenewmexican
5 Aug 2009, 5:48 AM
I have the following source artefacts.

From my gui code, I invoke the com.mystuff.dwrService.doLogin(userID,password); method. Which in turn invokes the DWRMethods.authenticateUser(userID,aPassword,handleAuthenticationResult) method.




On the server I can see that the call is made, because I log the authentication result
on the console.

The handleAuthenticationResult method sets a global variable window.authResult.
However, when I attempt to access window.authResult, I get an undefined error.

I'm porting an app from TibcoGI to ExtJs. Which part of this sequence of actions
is incorrect.

Thanks.




//: Inside myLogic.js

Ext.ns('com','com.mystuff');

com.mystuff.dwrService = function(){

var handleAuthenticationResult = function(serverReturnVal){
//: Setting the window.authResult here
window.authResult = serverReturnVal;

}


return {
// public scope (the members of this object will be available outside of this function.)
processIt : handleAuthenticationResult ,

doLogin : function(userID,aPassword){
//: making a DWR call
//: handleAuthenticationResult is the DWR callback method
DWRMethods.authenticateUser(userID,aPassword,handleAuthenticationResult);


}
}



}()

//: Java class
@DataTransferObject
public class AuthenticationResult {

public AuthenticationResult(){}

public AuthenticationResult(ServiceRecipient aLogin){

this.setLogin(aLogin);

}
/**
* @return Returns the login.
*/
public ServiceRecipient getLogin() {
return login;
}
/**
* @param login The login to set.
*/
public void setLogin(ServiceRecipient login) {
this.login = login;
}
/**
* @return Returns the simulation.
*/



/**
* @return Returns the userNotFound flag
*/
public boolean getUserNotFound() {
return userNotFound;
}

/**
* @param userNotFound The userNotFound to set.
*/
public void setUserNotFound(boolean userNotFound) {
this.userNotFound = userNotFound;
}

@RemoteProperty private ServiceRecipient login;
@RemoteProperty private boolean userNotFound;

}


//: Called from myGuiDefs.js

com.mystuff.dwrService.doLogin(userID,password);
//: After this method call, window.authResult should be defined

var recipientName = window.authResult.login.fullName;
/*
* Error occurs telling me that window.authResult is undefined.
*/

carol.ext
5 Aug 2009, 6:03 AM
The part that is wrong it thinking that the result of an asynchronous call will be available immediately instead of after the callback returns.

thenewmexican
5 Aug 2009, 6:14 AM
Thanks for the reply.

As per the DWR specs. The handleAuthenticationResult is a method that is called when the return value is available


.

Animal
5 Aug 2009, 6:18 AM
And thanks for that reply, but carol is correct.

You are accessing that result before the callback has been fired! It takes a loooong time (in computer terms) for the HTTP traffic to arrive at the server, get processed and then return.

Your DWR call returns IMMEDIATELY.

thenewmexican
5 Aug 2009, 6:24 AM
I appreciate the reply.
However I think that you are both incorrect.

//: From the DWR site
Writing JavaScript with DWR

DWR generates Javascript code that is similar to the Java code that exported using dwr.xml.


The biggest challenge in creating a remote interface to match some Java code across Ajax is the (usually) asynchronous nature of Ajax, compared to the synchronous nature of a normal Java call.




DWR solves this problem by introducing a callback function that is called when the data is returned from the server.





public class Remote {
public String getData(int index) { ... }
}

function handleGetData(str) {
alert(str);
}

Remote.getData(42, handleGetData);

//: handleGetData is called ONLY when the return value becomes available.

carol.ext
5 Aug 2009, 6:29 AM
Exactly, so you can access the data in a callback. NOT in the statement after the doLogin call that occurs before the callback.


com.mystuff.dwrService.doLogin(userID,password);
//: After this method call, window.authResult should be defined <<-- NO!!!!!!!

var recipientName = window.authResult.login.fullName;

Animal
5 Aug 2009, 6:30 AM
OK. We're all wrong.

You won't get anywhere like this you know.

thenewmexican
5 Aug 2009, 6:36 AM
So. What you're saying is. The doLogin method completes, before the callback method completes.

What does the JS call stack look like ??

I thought the call stack should be
1. doLogin()
2. handleAuthResult

And the calls are peeled off the stack in that order.

thenewmexican
5 Aug 2009, 6:37 AM
I'm just stating what the DWR specs say. And. Besides. This worked in TibcoGI.

Animal
5 Aug 2009, 6:39 AM
You have to read and visualize Javascript differently to other code.

Control jumps into it and dives back into the browser at any time. It does not progress from top top bottom serially.

Yes, control returns from the DWR call immediately. Return data is not available at that time. This is what "asynchronous" means.

All postprocessing of returned data must take place from within the callback.

thenewmexican
5 Aug 2009, 6:43 AM
I understand what async means full well. However. THAT. Is what toolkits life DWR were born to handle. The async nature of Ajax.

But. Again. This worked fine in Tibco. So. I work it out. But.
Thanks. again.

Animal
5 Aug 2009, 6:47 AM
OK. Have. it. your. own. way.

I've. been. using. DWR. for. several. years. now. No. problems. I. process. returned. data. in. the. callback. It's. how. it. is.

thenewmexican
5 Aug 2009, 8:22 AM
Thanks Animal. I really appreciate your help.
I understand what you're saying now.

I have to aaaaadjust my thinking accordingly for this project.