Globalisation of system messages in worklight 5.0.6 - ibm-mobilefirst

wil u pls help out from globalisation of system messages using
WL.ClientMessages.loading = "Custom loading";
which is declared globally in common/js file.
I have gone to worklight docs but i couldnt understand hw to translate it to differnt languages

A device's native system messages can be modified during application start-up by globally assigning a custom value to WL.ClientMessages.messageName before the wlCommonInit() function.
WL.ClientMessages.wlSettings = 'Custom Worklight Settings';
function wlCommonInit(){
As referenced in this post, the loading system message can only be modified when an application does not connect to the Worklight server on start-up.
var wlInitOptions = {
connectOnStartup : false,
System messages are defined in .../wlclient/js/messages.js and can only be modified at start-up in the above fashion. Application specific messages located in common/js/messages.js can be modified at run-time using JavaScript. For examples and additional information please consult IBM's Getting Started Page

WL.ClientMessages.loading = Messages.wrklight;
Will cause an error because the application messages in common/js/messages.js have not been loaded when this statement executes. To translate system messages I recommend using the device language and locale to select a language from a set of conditional statements. Here is a brief example:
if(WL.App.getDeviceLanguage() == 'en' && WL.App.getDeviceLocale() == 'en-US') {
WL.ClientMessages.loading = 'Custom Loading Message';
}

Related

CefSharp.BrowserSubProcess.Core WCF pipe failure

Our application is using CefSharp version 73.1.130. The issue only occurs on a small number of internal workstations within our organization. Worth noting, we are also seeing the same error with CefSharp version 92. Another strange thing is that it the issue is consistent, but only when the web apps are launched through certain navigations. Other navigations work consistently for these users.
We use RegisterJsObject to register a javascript object with browser. If I understand correctly, asynchronous binding is preferred moving forward.
The issue presents as strange/unexpected behavior in the hosted web application due to failure to retrieve context from the host WinForms application. The behavior would suggest a failure to register/bind the js object with the RegisterJsObject method. However, that method is not throwing an exception.
Enabled Cef logging showed the following error:
ERROR:JavascriptRootObjectWrapper.cpp(34)] IBrowserProcess is null, unable to bind object
After looking into the code, it appears the location that the value pointed to by "IBrowserProcess" is set is in WcfEnabledSubProcess::OnBrowserCreated (https://github.com/cefsharp/CefSharp/blob/cefsharp/73/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp). I was able to build CefSharp and add additional logging to that method.
On my workstation (I'm not affected by the issue), I get through OnBrowserCreated with no exceptions. However, on my coworkers workstation I see the following line is failing:
...
channelFactory->Open();
auto browserProcess = channelFactory->CreateChannel();
auto clientChannel = ((IClientChannel^)browserProcess);
try
{
clientChannel->Open(); <-- FAILS
browser->ChannelFactory = channelFactory;
browser->BrowserProcess = browserProcess;
}
catch (Exception^)
{
}
}
With the error:
There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)
Has anyone seen this issue before? I'm not sure how much this will help, but does anyone know if it's possible to enable WCF tracing with the CefSharp.BrowserSubProcess.exe. I have been trying this, but no luck so far.

How to access SAP OData messages in Kapsel offline app?

We are developing an SAP Fiori App to be used on the Launchpad and as an offline-enabled hybrid app as well using the SAP SDK and its Kapsel Plug Ins. One issue we are facing at the moment is the ODATA message handling.
On the Gateway, we are using the Message Manager to add additional information to the response
" ABAP snippet, random Gateway entity method
[...]
DATA(lo_message_container) = me->mo_context->get_message_container( ).
lo_message_container->add_message(
iv_msg_type = /iwbep/cl_cos_logger=>warning
iv_msg_number = '123'
iv_msg_id = 'ZFOO'
).
" optional, only used for 'true' errors
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = lo_message_container.
In the Fiori app, we can directly access those data from the message manager. The data can be applied to a MessageView control.
// Fiori part (Desktop, online)
var aMessageData = sap.ui.getCore().getMessageManager().getMessageModel().getData();
However, our offline app always has an empty message model. After a sync or flush, the message model is always empty - even after triggering message generating methods in the backend.
The only way to get some kind of messages is to raise a /iwbep/cx_mgw_busi_exception and pass the message container. The messages can be found, in an unparsed state, in the /ErrorArchive entity and be read for further use.
// Hybrid App part, offline, after sync and flush
this.getModel().read("/ErrorArchive", { success: .... })
This approach limits us to negative, "exception worthy", messages only. We also have to code some parts of our app twice (Desktop vs. Offlne App).
So: Is there a "proper" to access those messages after an offline sync and flush?
For analyzing the issue, you might use the tool ILOData as seen in this blog:
Step by Step with the SAP Cloud Platform SDK for Android — Part 6c — Using ILOData
Note, ILOData is part of the Kapsel SDK, so while the blog above was part of a series on the SAP Cloud Platform SDK for Android, it also applies to Kapsel apps.
ILOData is a command line based tool that lets you execute OData requests and queries against an offline store.
It functions as an offline OData client, without the need for an application.
Therefore, it’s a good tool to use to test data from the backend system, as well as verify app behavior.
If a client has a problem with some entries on their device, the offline store from the device can be retrieved using the sendStore method and then ILOData can be used to query the database.
This blog about Kapsel Offline OData plugin might also be helpful.

Worklight Analytics payload

Worklight 6.2.0, Mobile Web Environment
The Worklight Info Center offers three formulations for logging an analytic message
WL.Analytics.log('my record');
WL.Analytics.log({data: [1,2,3]});
WL.Analytics.log({data: [1,2,3]}, 'MyData');
I am successfully using the first of these, but the other two produce no analytics and my fail() function is not fired.
I see in the online tutorials a further formulation
WL.Analytics.log({_activity: "myActivity" });
this too produces no output.
Question: Are there other formulations that do work?
All calls other than
WL.Analytics.log('my record')
were intended for Analytics features that were not implemented or did not make it into the Worklight 6.2 release. Clearly this is not reflected in the documentation. I will open a defect to either have the logs searchable or have this limitation reflected in the documentation.
If the following call:
WL.Analytics.log({_activity: "myActivity" });
does not result in activities being searchable in the 'Activites' page of the Analytics console, then this is a defect for Worklight 6.2.
I can confirm that all of the above issues are fixed for the next release of Worklight (whether its through code fixes or documentation). If you need some of these fixes backported to a previous release of Worklight, please open a PMR so that we can begin that process.
I would suggest passing in the stringify property as true.
var obj = {name : "bob", age : 100};
WL.Logger.config({stringify : true, pkg: 'myActivity'});
WL.Logger.debug(obj);
If you want a pretty format you could pass in the pretty property
WL.Logger.config({stringify : true, pretty : true, pkg: 'myActivity'});
WL.Logger.debug(obj);
Hope this helps.

Sharing code between Worklight Adapters

In most cases I've dealt with so far the Worklight Adapter implementation has been pretty trivial, just a few lines of JavaScript.
On the current project, using WL 5.0.6, we have several adapters, each with several procedures. Our particular backends require some common logic to set up requests and interpret responses. Seems ideal for refactoring common code to shared library, execpt that as far as I can see there's no "library" concept in the adapter environment unless we want to drop down into Java.
Are there any patterns for code-reuse between adapters?
I think you are right. There is currently no way of importing custom JavaScript libraries.
There is a way to include/load Javascript files in Mozilla Rhino engine by using the "load(xyz.js)" function, but this will make your Worklight adapter undeployable.
But I've noticed, that this will make your Worklight adapter undeployable. If you deploy a second *.js file within an adapter, you'll get the following error message:
Adapter deployment failed: Procedure 'getStories' is not implemented in the adapter's JavaScript file.
It seems like Worklight Server can only handle one JavaScript file per adapter.
I have shared some common functionality between adapters by implementing the functionality in Java code and including the jar file in the Worklight war file. This came in handy to invoke stored procs via JDBC that can handle multiple out parms and also retrieving PDF content from internal backend services. The jar needs to be in the lib dir of the worklight.war web app that the adapter will be deployed to.
Example of creating a java object in the adapter:
var parm = new org.apache.http.message.BasicNameValuePair("QBS_Reference_ID",refId);
One way to share JavaScript between adapters is to follow a pattern somewhat like this:
CommonAdapter-impl.js:
var commonObject = {
invokeBackend: function(input, options) {
// Do stuff to check/modify input & options
response = WL.Server.invokeHttp(input);
// Do stuff to check/modify response
return response;
}
}
getCommonObject: function() {
return commonObject;
}
NormalAdapter-impl.js:
function getSomeData(dataNumber) {
var input = {
method: 'get',
returnedContentType: 'json',
path: '/restservices/getsomedata',
}
return _getCommonObject().invokeBackend(input);
}
function _getCommonObject() {
var invocationData = {
adapter: 'CommonAdapter',
procedure: 'getCommonObject',
parameters: []
}
return WL.Server.invokeProcedure(invocationData);
}
In this particular case, the common adapter is being used to provide a "wrapper" function around WL.Server.invokeHttp, but it can be used to provide any other utility functions as well.
The reason for this pattern in particular is that it allows the WL.Server.invokeHttp to run in the context of the "calling" adapter, which means the endpoint (hostname, port number, etc.) specified in the calling adapter's .xml file will be used. It does mean that the short _getCommonObject() function has to be repeated in each "normal" adapter, but this is a fairly small piece of boilerplate.
Note that this pattern has been used with Worklight 6.1 - there is no guarantee it will work in future or past versions.

Remoting with AIR

Hi I am trying to set up remoting in an AIR app.
Does anyone know if I need to define a context-root in the compiler settings.
Can't seem to find any articles about setting it up, only in flex.
Thanks
compiler setting looks like:
-services "X:\tomcat\webapps\blazeds\WEB-INF\flex\services-config.xml"
however, if you want AIR to work over http you have to setup it abit different than a webapp. dunno why, but when using a webapp its enough to setup the flex-server on blazeDS or whatver backend you use and than use something like
protected function createData(event:MouseEvent):void
{
var javaObject : RemoteObject = new RemoteObject("YOUR_CONFIGURED_JAVA_CLASS");
javaObject.showBusyCursor = true;
var token : AsyncToken = javaObject.YOUR_JAVA_METHOD();
token.addResponder(new mx.rpc.Responder(dataResult,handleFault));
}
but when using AIR you HAVE to setup a destination and endpoint, otherwise it will fail to connect and you will end up with and error like
'Channel.Connect.Failed error
NetConnection.Call.Failed: HTTP:
Failed: url:
'http://ain.swf/blazeds/messagebroker/amf''
so, for AIR apps you have add the following
javaObject.endpoint = "http://IP:PORT/blazeds/messagebroker/amf";
javaObject.destination = "hello";
where hello again is the config'd java-class you're calling.
hope that helped.