InvokeMethod with Parameters

Requirement

Capture a response from client side, and send it to the server

Option 1: Use a profile attribute

Profile attributes are dirty for a number of reasons, this post by Mike M. Lin, highlights the issues very well.

Option 2: Invoke a server side business service

This option requires a business service to be exposed to the browser, and requires abit more code to invoke, but it is certainly an option, especially if you need a return value. The only caveat is that the code on the server dosnt have direct context of the BC, but it is a good way to encapsulate your logic.

Option 3: Invoke method??

InvokeMethod in server script has no parameters, InvokeMethod in browser script contains the "inputPropSet" parameter, but unfortunately it can not be used to pass data to the server side, however with a little fancy foot work, we can bend InvokeMethod to handle parameters.

The solution entails scripting, and abuse of a Siebel staple, so its not for the faint hearted, but I know if you've read this far, then you are here to see Siebel bend, so read on...

Modified Requirement

Pass an array of data eg. ["I","love","disco"] and send it from browser side to server side

Solution

1. Create a button on an Applet

2. Set the Method Invoked property = "EventMethodDataHandler"

This method is only a proxy, the real data shuttling happens in the code below

3. Create the following browser script in Applet_PreInvokeMethod

function Applet_PreInvokeMethod (name, inputPropSet)
{
var iRet="ContinueOperation";
var aArr=["I","Love","Disco"];
switch(name){
case "EventMethodDataHandler":
this.InvokeMethod("EventMethod|YourBrowserMethodName|"+aArr.join(","));
break;
}
return iRet;
}

The above code constructs a dynamic InvokeMethod that appends data to the method name itself.

4. Create the following server script in BusComp_PreInvokeMethod

function BusComp_PreInvokeMethod (MethodName){
//ComplexMethod - processing for invoked methods with args
var aComplexMethod=MethodName.split("|");
if(aComplexMethod[0]=="EventMethod"){
iRet= PreInvokeMethod_ComplexMethod(aComplexMethod);
return iRet;
}
}
function PreInvokeMethod_ComplexMethod(aComplexMethod){
var sMethod=aComplexMethod[1]; //Custom Method
var sArg1=aComplexMethod[2]; //Args
switch(sMethod){
case "YourBrowserMethodName":
var aArrFromBrower=sArg1.split(",");
//perform your processing here
break;
}
}

By using a standard namespace, we can detect whether the method invoked is a Complex method or a normal method invocation, and handle it accordingly.

In the above example. The method invoked is

EventMethod|YourBrowserMethodName|I,Love,Disco

The server code intercepts method this by detecting the namespace, and converts the method name into an array. The last argument of the array is a String representation of our data which was set dynamically by the browser. This data can be any type of object that can be serialised, but InvokeMethod was not designed to transport data, so if you do decide to use this option, restrict it to small amounts of data.

Beware that Siebel encodes HTML entities, so if you want to use these type of characters as values in your data, you'll need to build some helper utilities to deal with converting them.

This method of parametizing the InvokeMethod is not limited to browser script, but it does open doors to perform funky browser/server co-ordination and offers an alternative to abusing your profile attributes.


Reactions:

2 comments:

  1. This may be an alternative... it combines idea 2 and 3... http://yetanothersiebelframework.blogspot.com/2010/06/from-browser-side-down-then-back-up.html

    I never really got round to documenting the thing fully, but briefly the principles of how the Framework allow data/parameters pass from client side to server side and back are:

    1. use a single named client service that the framework code wraps - so all calls from client call that, and all returns use the same return
    2. use "JSON like" code to flatten an un-flatten objects/parameter arrays (this allows complex arguments/objects be passed as a single string - crucial for the return value

    Having all client to server calls routing through the one service saves having to write code on each specific buscomp/service etc where you want to call methods...

    ReplyDelete
  2. nice article its explore and provide technical solutions of business problems that are documented as product limitations, impossible to achieve.

    ReplyDelete

Comments are open to all, please make it constructive.