Mirth: Evaulating SWITCH versus IF Statement - mirth

I'm using a product called Mirth (version 3.6) to execute transform code. It doesn't seem to have an interactive debugger so can anyone explain why the following code in a destination transform will only log from the IF statement and not from the SWITCH statement? Works perfectly from regular java running in Eclipse but this code is executing inside a JavaScript engine that Mirth uses (Rhino if I'm not mistaken).
for each (node in msg['PID'].children())
{
if(node.name() == "PID.3")
{
logger.info("IF Succeeded");
}
switch(node.name())
{
case "PID.3":
logger.info("SWITCH Succeeded"); // This line never logs
break;
}
}

This is a common issue with Mirth Connect since it uses Rhino as it's engine (uses java as well as javascript).
The Switch statement doesn't work with a Java String object
The simple solution is to convert any unknown string type to a native JS string by concatenating an empty string to the questionable string (i.e. str + '')
// See in action
for each (node in msg['PID'].children())
{
var nodeName = node.name();
if (nodeName != "PID.3")
{
continue;
}
var type = typeof(nodeName);
logger.debug('NodeName: ' + nodeName + '; Type: ' + type);
if (type == 'object') {
logger.debug('Type is object');
if (nodeName instanceof String) {
logger.debug('Object is Java String instance');
} else {
logger.debug('Object is not Java String instance');
}
} else if (type === 'string') {
logger.debug('Type is JS string.');
} else {
logger.debug('Type is not object or string. Type: ' + type);
}
// Works with String object or JS string
if (nodeName == "PID.3")
{
logger.info("IF Succeeded");
}
// Only works with JS string
switch (nodeName)
{
case "PID.3":
logger.info("SWITCH Succeeded"); // This line never logs
break;
default:
logger.info("SWITCH not matched: " + nodeName);
break;
}
logger.debug('Convert to JS string');
nodeName = nodeName + '';
type = typeof(nodeName);
logger.debug('Converted Type: ' + type);
if (type == 'object') {
logger.debug('Converted Type is object');
if (nodeName instanceof String) {
logger.debug('Converted Object is String instance');
} else if (nodeName instanceof string) {
logger.debug('Converted Object is string instance');
} else {
logger.debug('Converted Object is not Java String instance');
}
} else if (type === 'string') {
logger.debug('Converted Type is JS string.');
} else {
logger.debug('Converted Type is not object or string. Type: ' + type);
}
switch(nodeName)
{
case "PID.3":
logger.info("SWITCH with js string Succeeded");
break;
default:
logger.info("SWITCH with js string not matched: " + nodeName);
break;
}
break;
}

Related

Get Method Call arguments in flutter window

Does anyone know how to get an argument pass by MethodChannel in windows?
Here is my code to send and receive data.
I need to get data value in string type
String data = "Some data";
await platform.invokeMethod("OpenViewer", {"data":data});
channel->SetMethodCallHandler([](const flutter::MethodCall<>& call, std::unique_ptr<flutter::MethodResult<>> result)
{
// check method name called from dart
if (call.method_name().compare("OpenViewer") == 0) {
}
else {
result->NotImplemented();
}
});
you could use something like below
if (method_call.method_name().compare("launch") == 0) {
std::string url = GetUrlArgument(method_call);
if (url.empty()) {
result->Error("argument_error", "No URL provided");
return;
}
std::optional<std::string> error = LaunchUrl(url);
if (error) {
result->Error("open_error", error.value());
return;
}
result->Success(EncodableValue(true));
For more read here from url_launcher

After updating to unity 2021.1.13.f1 isNetworkError and isHttpError is already obselete

if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
Does anyone know how to replace this code properly to the updated one
Starting from Unity 2020.2 you now use UnityWebRequest.result
Example from UnityWebRequest.Get
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
string[] pages = uri.Split('/');
int page = pages.Length - 1;
switch (webRequest.result)
{
case UnityWebRequest.Result.ConnectionError:
case UnityWebRequest.Result.DataProcessingError:
Debug.LogError(pages[page] + ": Error: " + webRequest.error);
break;
case UnityWebRequest.Result.ProtocolError:
Debug.LogError(pages[page] + ": HTTP Error: " + webRequest.error);
break;
case UnityWebRequest.Result.Success:
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
break;
}
}
Or the simplier example from UnityWebRequest.Post
WWWForm form = new WWWForm();
form.AddField("myField", "myData");
using (UnityWebRequest www = UnityWebRequest.Post("https://www.my-server.com/myform", form))
{
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
}
I solve mine like that!
instead using: if(www.isNetworkError)
I wrote: if(www.result == UnityWebRequest.Result.ConnectionError)
Full example is below:
IEnumerator Get(string url)
{
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.ConnectionError)
{
Debug.LogError(www.error);
}
}
}
Replace "www.isHttpError" with "(www.result== UnityWebRequest.Result.ProtocolError)" and "www.isNetworkError" with "(www.result == UnityWebRequest.Result.ConnectionError)".
Assuming www means the request object.

How can you setup a flutter rawkeyboardlistener to read {} (curly brackets) instead of square brackets?

I have a flutter solution that interprets a QR code via a scanning device. I use the RawKeyboardListener to read the scanned QR code that then parses it into a variable.
The QR value is an object {something: somethingelse}, but when read by the RawKeyboardListener, it reads the {} as [] and as a result, the object is then invalid.
String runtime = event.runtimeType.toString();
if (event.data.logicalKey != LogicalKeyboardKey.enter) {
setState(() {
scannedItem += runtime == 'RawKeyUpEvent' ? event.data.keyLabel : '';
});
} else if (scannedItem != '') {
setState(() {
var data = json.decode(scannedItem);
});
}
I played around with the solution and ended up fixing it, though I do feel there is a better way of resolving this
if (event.data.isShiftPressed) {
switch (event.data.logicalKey.debugName) {
case 'Bracket Left':
keyLabel = '{';
break;
case 'Bracket Right':
keyLabel = '}';
break;
case 'Quote':
keyLabel = '"';
break;
case 'Semicolon':
keyLabel = ':';
break;
default:
keyLabel = keyLabel.toUpperCase();
break;
}
}

Using Post Request return a multiple values in Unity

I am new to Unity i have created a Post Request from that i want to return the Authentication-Token Header and authorization header and some required json data here is my code
private IEnumerator BasketId()
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
string token = request.GetResponseHeader("Authentication-token");
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
}
else
{
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
Debug.Log(obj.Uri);
Debug.Log("Authentication-Token: " + token);
yield return obj.Title;
yield return token;
}
}
}
so i could i return the values. Please help me.
Because Coroutine is not immediate (blocking) so you won't be able to return the response directly. What you need to do is to have an event or callback that will be called when your request completed.
Here is how you can achieve it by passing the callback as argument:
private IEnumerator GetBasketId(System.Action<string, BasketId> callback)
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
if (callback != null)
{
callback(null, null);
}
// callback?.Invoke(null, null); // for short
}
else
{
if (callback != null)
{
string token = request.GetResponseHeader("Authentication-token");
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
if (callback != null)
{
callback(token, obj);
}
// callback?.Invoke(token, obj); // for short
}
}
}
}
so when you want to start the request simply call something like:
StartCoroutine(GetBasketId((token, basketId) =>
{
if (string.IsNullOrEmpty(token))
{
// Handle error
}
else
{
// Handle success
Debug.Log("Token: " + token);
Debug.Log(basketId.Title);
}
});

MobileFirst 6.3 invoking backend service created adapter procedure

I am having a hard time working out how to invoke my adapter which MobileFirst has created for me using the Discover Back End Service feature.
I created my adapter, and I am not using the following code to try and call it:
function callService(){
alert("Calling into Backend");
var options = {
onSuccess : loadSuccess,
onFailure : loadFailure,
invocationContext: {}
};
var params = {"itemRequiredReference":10};
var invocationData = {
adapter : 'SoapAdapter1',
procedure : 'inquireSingleService_inquireSingle',
parameters : [params]
};
WL.Client.invokeProcedure(invocationData, options);
}
But this does not seem to work. I get the error :
{"status":200,"invocationContext":{},"invocationResult":{"statusCode":500,"errors":[],"isSuccessful":true,"Envelope":{"SOAP-ENV":"http://schemas.xmlsoap.org/soap/envelope/","Body":{"Fault":{"":"","detail":{"CICSFault":{"CDATA":"DFHPI1010 02/02/2015 22:11:37 GENAPPA1 CPIH 00518 XML generation failed. A conversion error (INVALID_ZONED_DEC) occurred when converting field itemReferenceNumber for WEBSERVICE inquireSingleWrapper.","xmlns":"http://www.ibm.com/software/htp/cics/WSFault"}},"faultcode":"SOAP-ENV:Server","faultstring":"Conversion to SOAP failed"}},"soap":"http://schemas.xmlsoap.org/soap/envelope/"},"statusReason":"Internal Server Error","responseHeaders":{"Date":"Mon, 02 Feb 2015 22:11:37 GMT","Content-Length":"000000000000608","Content-Type":"text/xml; charset=UTF-8","Connection":"Keep-Alive","Server":"IBM_CICS_Transaction_Server/5.2.0(zOS)"},"warnings":[],"responseTime":578,"totalTime":581,"info":[]}}
The generated adapter code looks like this :
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Generated code - Do not edit //
// //
// This is a SOAP adapter that was auto-generated by Worklight for invocation of specific SOAP-based services. //
// The adapter may invoke more than one service as long as they are all from the same enpdpoint (server host). //
// Each adapter procedure matches a single operation for the same endpoint server and accepts: //
// params - Serialized JSON representation of the XML-based SOAP body to be sent to the service //
// headers - Custom HTTP headers to be specified when invoking the remote service. It is a JSON object with //
// the headers names and values. E.g. { 'name1' : 'value1', 'name2' : 'value2' } //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function inquireSingleService_inquireSingle(params, headers){
var soapEnvNS = '';
// The value of 'soapEnvNS' was set based on the version of the SOAP to be used (i.e. 1.1 or 1.2).
soapEnvNS = 'http://schemas.xmlsoap.org/soap/envelope/';
// The following mappings object was autogenerated from the XML schema of the input message to the service.
// It is being used to support a params JSON when invoking this procedure that don't specify the namespace
// prefix nor specifying whether a property is attribute or not.
//
// The 'roots' object has the list of message parts within the invocation SOAP message. Each entry has a
// mapping between the root element name and its namespace prefix and type.
// Each root object may define 'nsPrefix' and 'type'. Both are optional - If there is no need for a NS prefix
// then the 'nsPrefix' should not be specified. If the element is a simple type then the 'type' should not be
// specified.
//
// The 'types' object has a list of types each defining the children of the type and the definition of each
// child. If the child is a complext type, the 'type' property has a reference to the child type definition.
// Each child object may define:
// 'nsPrefix' (optional) - Holds the namespace prefix to be attached to the element. If there is no need for
// a NS prefix then the 'nsPrefix' should not be specified.
// 'type' (optional) - If the element is a simple type then the 'type' should not be specified. If it is an
// attribute then 'type' should have the value of '#'. Otherwise the value of 'type' is a reference to the
// type definition within the 'types' object.
var mappings = {
roots: {
'inquireSingleRequest': { nsPrefix: 'reqns', type: 'reqns:inquireSingleRequest' }
},
types: {
'reqns:inquireSingleRequest': {
children: [
{'itemRequiredReference': { nsPrefix: 'reqns' }}
]
}
}
};
var namespaces = 'xmlns:resns="http://www.exampleApp.inquireSingleResponse.com" xmlns:reqns="http://www.exampleApp.inquireSingleRequest.com" xmlns:tns="http://www.exampleApp.inquireSingleResponse.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
var request = buildBody(params, namespaces, mappings, soapEnvNS);
var soapAction = '';
return invokeWebService(request, headers, soapAction);
}
function buildBody(params, namespaces, mappings, soapEnvNS){
var body =
'<soap:Envelope xmlns:soap="' + soapEnvNS + '">\n' +
'<soap:Body>\n';
var fixedParams = {};
for (var paramName in params) {
if (mappings['roots'][paramName]) { //There is mapping for this param
var root = mappings['roots'][paramName];
var name = paramName;
if (root['nsPrefix'])
name = root['nsPrefix'] + ':' + paramName;
fixedParams[name] = handleMappings(params[paramName], root['type'], mappings['types']);
}
else {
fixedParams[paramName] = params[paramName];
}
}
body = jsonToXml(fixedParams, body, namespaces);
body +=
'</soap:Body>\n' +
'</soap:Envelope>\n';
return body;
}
function handleMappings(jsonObj, type, mappings) {
var fixedObj = {};
var typeMap = mappings[type]['children']; //Get the object that defines the mappings for the specific type
// loop through the types and see if there is an input param defined
for(var i = 0; i < typeMap.length; i++) {
var childType = typeMap[i];
for(var key in childType) {
if(jsonObj[key] !== null) { // input param exists
var childName = key;
if (childType[key]['nsPrefix'])
childName = childType[key]['nsPrefix'] + ':' + key;
if (!childType[key]['type']) //Simple type element
fixedObj[childName] = jsonObj[key];
else if (typeof jsonObj[key] === 'object' && jsonObj[key].length != undefined) { //Array of complex type elements
fixedObj[childName] = [];
for (var i=0; i<jsonObj[key].length; i++)
fixedObj[childName][i] = handleMappings(jsonObj[key][i], childType[key]['type'], mappings);
}
else if (typeof jsonObj[key] === 'object') //Complex type element
fixedObj[childName] = handleMappings(jsonObj[key], childType[key]['type'], mappings);
else if (childType[key]['type'] == '#') //Attribute
fixedObj['#' + childName] = jsonObj[key];
}
}
}
return fixedObj;
}
function getAttributes(jsonObj) {
var attrStr = '';
for(var attr in jsonObj) {
if (attr.charAt(0) == '#') {
var val = jsonObj[attr];
attrStr += ' ' + attr.substring(1);
attrStr += '="' + xmlEscape(val) + '"';
}
}
return attrStr;
}
function jsonToXml(jsonObj, xmlStr, namespaces) {
var toAppend = '';
for(var attr in jsonObj) {
if (attr.charAt(0) != '#') {
var val = jsonObj[attr];
if (typeof val === 'object' && val.length != undefined) {
for(var i=0; i<val.length; i++) {
toAppend += "<" + attr + getAttributes(val[i]);
if (namespaces != null)
toAppend += ' ' + namespaces;
toAppend += ">\n";
toAppend = jsonToXml(val[i], toAppend);
toAppend += "</" + attr + ">\n";
}
}
else {
toAppend += "<" + attr;
if (typeof val === 'object') {
toAppend += getAttributes(val);
if (namespaces != null)
toAppend += ' ' + namespaces;
toAppend += ">\n";
toAppend = jsonToXml(val, toAppend);
}
else {
toAppend += ">" + xmlEscape(val);
}
toAppend += "</" + attr + ">\n";
}
}
}
return xmlStr += toAppend;
}
function invokeWebService(body, headers, soapAction){
var input = {
method : 'post',
returnedContentType : 'xml',
path : '/exampleApp/inquireSingleWrapper',
body: {
content : body.toString(),
contentType : 'text/xml; charset=utf-8'
}
};
WL.Logger.error("ANDY:"+body.toString());
//Adding custom HTTP headers if they were provided as parameter to the procedure call
//Always add header for SOAP action
headers = headers || {};
if (soapAction != 'null')
headers.SOAPAction = soapAction;
input['headers'] = headers;
return WL.Server.invokeHttp(input);
}
function xmlEscape(obj) {
if(typeof obj !== 'string') {
return obj;
}
return obj.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, '&apos;')
.replace(/</g, '<')
.replace(/>/g, '>');
}
I am a little lost - the parameters parameter on the invocationData object is what needs to be fixed - but its really very unclear what mapping as a json object I am meant to be passing as a parameter. Can somebody please show me what parameter I need to pass to set itemRequiredReference to the number 30.
If you need the WSDL I used to generate the service this is what I used : http://we.tl/fHgRos3f4e
This is the service being invoked from soapUI #idan :
Well I finally found a useful documentation page here :http://www-01.ibm.com/support/knowledgecenter/SSHS8R_6.3.0/com.ibm.worklight.dev.doc/dev/c_invocation_generated_soap_adapter.html
and the solution was to set parameters variable to :
var params = {"inquireSingleRequest": {"itemRequiredReference": "10"}}
var invocationData = {
adapter : 'SoapAdapter1',
procedure : 'inquireSingleService_inquireSingle',
parameters : [params]
};
This allowed it to work perfectly.