Friday, September 23, 2011

Gotcha when executing Javascript from a backing bean.

Earlier I had discussed about how to inject and fire JavaScript on the browser from a backing bean. This is an invaluable tool for some corner cases and can make life easier , however there is a gotcha here when we try to do things in a sequential order after we inject the JavaScript. Its a subtlety that would go unnoticed for most people too, so that makes it noteworthy since knowing this can save us a lot of time spent on debugging.

Take a look at the code below : 
FacesContext fctx = FacesContext.getCurrentInstance();
StringBuilder script = new StringBuilder();
script = script.append("alert('Calling Service');");
Service.getRenderKitService(fctx,ExtendedRenderKitService.class)
.addScript(fctx,script.toString());


The code when set as the action for a command component will execute and display a browser dialog with the message "Calling Service". Lets say there are things you want to execute after the browser popup is launched like call a WebService or execute a query. So you make the code :
FacesContext fctx = FacesContext.getCurrentInstance();
StringBuilder script = new StringBuilder();
script = script.append("alert('Calling Service');");
Service.getRenderKitService(fctx,ExtendedRenderKitService.class)
.addScript(fctx,script.toString());
WebServiceProxy.invokeWSmethod() // assume we call a synchronous WebService.


What one might expect to happen is for the message to appear and the web service to be invoked(in that order). But what happens in reality is that the web service is invoked and then the message appears.This is because the java script is executed only after the method finishes (I'm assuming here that it executes when the call stack is empty). This order of execution is relevant when we want to use JavaScript to show a dialog or an af:popup that should be triggered first(executed on the browser) before executing an operation. The obvious solution for this would be to split up the javascript and the actual operation in to two methods on your backing bean and just run the JavaScript part first and then use a call back method in your backing bean (using a server listener) to run the actual operation. A good example of how this can be done in practice is described here.

3 comments:

  1. This execution of file from backing bean makes coding easy. It’s easy than other coding.
    http://www.joomladesignservices.com/684-going-mobile-with-your-joomla-cms-portal.html

    ReplyDelete
  2. Pretty interesting post! Thanks it was interesting. on website

    ReplyDelete
  3. hi,
    How to call existing JavaScript function that take an Arguments.

    I want to pass some variables from the Bean to to a JavaScript function that take an arguments.

    ReplyDelete