Go to primary content
Siebel CRM Siebel Mobile Guide: Disconnected
Siebel Innovation Pack 2016, Rev. C
E52427-01
  Go to Documentation Home
Home
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
    View PDF

Migrating Siebel Mobile Disconnected From Asynchronous to Synchronous Programming Model

Siebel Mobile disconnected uses a synchronous programming model where $.callback and $.setReturnValue are not required. Previous releases of Siebel Mobile, prior to Siebel Innovation Pack 2016, used an asynchronous programming model where business services used a $.callback and $.setReturnValu for every method.


Note:

Customers who have written their own JavaScripts for Siebel Mobile disconnected must complete this task. This task is not required for customers planning to use Siebel Mobile disconnected for the first time with Siebel Invocation Pack 2016.

Migrating Siebel Mobile disconnected from an asynchronous to a synchronous programming model involves the following

To assist you in migrating Siebel Mobile disconnected JavaScript code from an asynchronous to a synchronous programming model, a migration tool (async2sync.pyc) is provided. For more information about the JavaScript migration tool, see "About the JavaScript Migration Tool".

About the JavaScript Migration Tool

The JavaScript migration tool, async2sync.pyc, is located in the following custom folder:

eappweb\PUBLIC\scripts\siebel\offline\custom

Python v2.x is required and must be installed to use the JavaScript migration tool.

The purpose of the JavaScript migration tool is to assist you in migrating application scripts from an asynchronous to a synchronous programming model. You can run the migration tool in debug mode (which is the default mode). Debug mode keeps the debug information in the output js file.

The JavaScript migration tool has the following limitations:

  • It cannot identify exactly which functions are asynchronous or synchronous.

    It can handle native asynchronous functions (which contain $.setReturnValue or $.callback). However, it cannot handle the synchronous wrapper for asynchronous functions. Documented APIs are provided within the tool.

  • It cannot exactly identify whether or not the caller should receive a return value from the functions.

Modifying Identified Patterns in the Existing Code Base

There are certain identified patterns in the existing code base that must be modified when migrating Siebel Mobile disconnected from an asynchronous to a synchronous programming model, and the purpose of this topic is to highlight those patterns.

Patterns in the existing code that must be modified include the following:

  1. Add a return value to the end of all asynchronous functions, for example, as follows:

    BusComp.prototype.SetFieldValueX = function (fieldName, fieldData,
    bSkipValidate, bSkipMvgCheck, bSkipED) {
    var currRetValue={err:false}, retObj;
    // code body
    return(currRetValue);
    }

    Asynchronous functions typically declare the local function.

  2. The Return value in asynchronous functions must return the currRetValue.

    For example, change the following:

    return;
    

    To the following:

    return currRetValue;
    

    If the return value already returns an object (obj), it raises a conflict and must be manually fixed, for example, as follows:

    return someObj;
    
  3. The setReturnValue value must set the currRetValue value.

    For example, change the following:

    $.setReturnValue({ err: true, retVal: data }); 

    To the following:

    currRetValue={ err: true, retVal: data }; 
    1. If setReturnValue returns the current function, then change the following for example:

      $.setReturnValue({ err: true, retVal: data });
      return;

      To the following:

      currRetValue={ err: true, retVal: data }; 
      return currRetValue;
    2. If setReturnValue passes the value to the next $.callback, then change the following:

      $.setReturnValue({ err: true, retVal: data }); 
      . . . //some code branch
      $.callback(this, function(retObj) {
      . . . //some code in call back
      });

      To the following:

      currRetValue={ err: true, retVal: data }; 
      . . . //some code branch
      retObj = currRetValue;
      . . . //some code in call back
  4. All calls to the asynchronous function must receive the synchronous value.

    For example, change the following:

    asyncFunc(args); 

    To the following:

    currRetValue=asyncFunc(args); 
  5. Remove all $.callbacks, for example, as follows:

    someAsyncFunc(); 
    $.callback(scope, function(retObj) {
    ...//some code in call back
    });
    1. If there is a retObj argument, then change the $.callback to the following for example:

      currRetValue=someAsyncFunc(); 
      retObj=currRetValue;
      ...//some code in call back
    2. If there is no retObj argument, then change the $.callback from the following:

      someAsyncFunc(); 
      $.callback(scope, function() {
      ...//some code in call back
      });

      To the following:

      currRetValue=someAsyncFunc(); 
      ...//some code in call back
    3. Most $.callback functions take an argument with the retObj name, but if the argument has a different retObj name, then declare a new local variable for example as follows:

      var someOtherRetObj = currRetValue;
      
    4. If the $.callback function is a handler, then change the following for example:

      someAsyncFunc(); 
      $.callback(this, doneHandler);

      To the following:

      currRetValue=someAsyncFunc(); 
      retObj=currRetValue;
      currRetValue=doneHandler.call(this,retObj)
  6. Remove nested functions in asynchronous functions.

    • Reuse currRetValue/retObj in nested functions.

    • Replace nested functions using $.setReturnValue and $.callback with currRetValue/retObj.

For example, migrate the following:

BusComp.prototype.SetFieldValueX = function (fieldName, fieldData, bSkipValidate, bSkipMvgCheck, bSkipED) {
if (this.IsDeletePending()) {
this.WriteRecord();
$.callback(this,function(retObj){
if(retObj.err){
$.setReturnValue(retObj);//sync:remove:continue
}else{
SetFieldValueUpdate.call(this,fieldName,bPicked,fieldData);
}
});
}else{
SetFieldValueUpdate.call(this,fieldName,bPicked,fieldData);
}
$.callback(this, function (retObj) {
if(!retObj.err){
SetFieldValuePostCall.call(this,fieldName,bPicked,inputObj,psInputArgs);
$.callback(this,function(retObj){
$.setReturnValue(retObj);
});
}else{
$.setReturnValue(retObj);
}
});
}

To the following:

BusComp.prototype.SetFieldValueX = function (fieldName, fieldData, bSkipValidate, bSkipMvgCheck, bSkipED) {
var currRetValue={err:false}, retObj;
if (this.IsDeletePending()) {
currRetValue=this.WriteRecord();
retObj=currRetValue;
//$.callback(this,function(retObj){
if(retObj.err){
currRetValue=(retObj);
}else{
currRetValue=SetFieldValueUpdate.call(this,fieldName,bPicked,fieldData);
}
//});
}else{
currRetValue=SetFieldValueUpdate.call(this,fieldName,bPicked,fieldData);
}
retObj=currRetValue;
//$.callback(this, function (retObj) {
if(!retObj.err){
currRetValue=SetFieldValuePostCall.call(this,fieldName,bPicked,inputObj,psInputArgs);
retObj=currRetValue;
currRetValue=(retObj);
}else{
currRetValue=(retObj);
}
//});
return(currRetValue);
}