Calling an SQL adapter from another SQL adapter doesnt work - ibm-mobilefirst

pls. is there any idea or suggestion wy call from an SQL adapter to another SQL adapter doesnt work ?
i use WL.Server.invokeProcedure.({adapter : "SQL_Adapter",procedure : "procedure name in the another adapter"}). it seems that function doesnt check the existence of the adapter and procedure parameters and work with any arbitrary string even for non-existing adapter/procedure. Result is always undefined object returned from the call
i am using Worklight 6.1.0.01.20140311-2356 on Windows server
both adapters works fine and are used regularly from client devices
the "server" adapter (MS SQL) is used for push notification and defines event source
the "client" adapter (DB2) is normal one.
there is piece of code:
var result = getAllUsersFromSQLPushNotificationAdapter();
if (result){
WL.Logger.info("test1" + result.isSuccessful); //i got false
WL.Logger.info("test2" + result.errorMessages); //i got undefined
WL.Logger.info("test3 " + result.resultSet); //i got undefined
//result = result["invocationResult"]["resultSet"];
for (var i = 0; i < result.resultSet.length; i++) {
//result[i].Category ";
}
WL.Logger.info("Number of users: " + result.resultSet.length);
}
function getAllUsersFromSQLPushNotificationAdapter(){
return WL.Server.invokeProcedure({
adapter : "CZU_SQL",
procedure : "getAllUsers"});
}
thank you

Try something like below.In getDataSuccess() get the results and use it.
var invocationData = {
adapter : 'ADAPTER_NAME',
procedure : 'PROCEDURE_NAME'
};
WL.Server.invokeProcedure(invocationData,{
onSuccess : getDataSuccess,
onFailure : getDataFailure,
});
For debugging purpose check the Success and failure function results. if you are not able to call another adapter procedure please post the error from failure function.

Related

Using setTimeout in Worklight adapter procedure

I've tried to use setTimeout in Worklight adapter procedure. It doesn't work.
WLSE0099E: An error occurred while invoking procedure [project BusinessBank]PushAdapter/submitNotificationFWLSE0100E: parameters: [project BusinessBank]
ReferenceError: "setTimeout" is not defined. (PushAdapter-impl.js#37)
I need to hold sending the push notification after invoking adapter procedure. It's need for the demo. My code example:
WL.Server.createEventSource({
name: 'PushEventSource',
onDeviceSubscribe: 'deviceSubscribeFunc',
onDeviceUnsubscribe: 'deviceUnsubscribeFunc',
securityTest:'AngularStarter-strong-mobile-securityTest'
});
function deviceSubscribeFunc(userSubscription, deviceSubscription){}
function deviceUnsubscribeFunc(userSubscription, deviceSubscription){}
function submitNotification(userId, notificationText) {
var userSubscription = WL.Server.getUserNotificationSubscription('PushAdapter.PushEventSource', userId);
if (userSubscription == null) {
return { result: "No subscription found for user :: " + userId };
}
var badgeDigit = 1,
notification = WL.Server.createDefaultNotification(notificationText, badgeDigit, {custom: "data"});
setTimeout(function() {
WL.Logger.debug("submitNotification >> userId :: " + userId + ", text :: " + notificationText);
WL.Server.notifyAllDevices(userSubscription, notification);
},5000);
return {
result: "Notification sent to user :: " + userId
};
}
If you're actually about about JavaScript method setTimeout, it will help if you'll add some code example of what exactly you're trying to do, given this is a programming Q&A website and all.
If you're demoing your app using Worklight Studio, there is no need to implement a timeout.
Open the app, login, subscribe to notifications, close the app. Then, right-click on the adapter and select Run As > Invoke Worklight procedure and add a username in text (for example: "myuser","mytext"). And that's it... the notification will be sent. Whenever you want it to be sent.
Otherwise,
There is no such thing as setTimeout for an adapter procedure...
See here: How to increase the adapter procedure timeout value in Worklight?
To set a timeout to a procedure, in the adapter XML file:
<procedure name="nameHere" requestTimeoutInSeconds="valueHere"/>
Please review the IBM Worklight Knowledge Center and training modules.
setTimeout API belongs to a global window object. basically using it the way you do is a shortcut to window.setTimeout().
Since adapter is not a browser but a server runnable code it doesn't have a global window object, therefore you have no setTimeout API.

invalid 'in' operand profile in worklight.js

I have two Worklight apps an one SQL-adapter in one project. the first app is the client app and works perfectly well. the second one is the the managment app which is using the same SQL-Adapter. they also call the same procedure, which makes a SQL-statement and returns the results. But when initializing the procedure from the controller app I am getting an error:
TypeError: invalid 'in' operand profile worklight.js:4039
Adapter-Procedure:
var selectStatement = WL.Server.createSQLStatement("select TITLE, BODY, DATE from MESSAGES where DATE>?");
function getMessages(param1) {
return WL.Server.invokeSQLStatement({
preparedStatement : selectStatement,
parameters : [param1]
});
}
Call from the Controller:
function getMessages(){
console.log("lala");
var invocationData = {
adapter : 'ClientAdapter',
procedure : 'getMessages',
parameters: ['2014-07-21 00:00:00.000000']
};
WL.Client.invokeProcedure(invocationData, {
onSuccess : success,
onFailure : failure
});
function success(result){
console.log("Successfully gathered Messages");
}
function failure(ErrorObject){
console.log("ERROR: could not get Messages/n" + ErrorObject);
}
}
I don't get how there can be an error there because i never touch that file (to be honest: I don't even know where it's located in my Project) and in the web inspector it looks the same in both apps.
The only difference is that I'm using Bootstrap in the contorller app instead of jquery mobile.
Any ideas how to fix it or work around?
Sincerely
Max
EDIT: Added code

How do I programmatically pass parameters for a query in worklight adapters?

I am able to create a worklight adapter, deploy it and invoke it by passing the parameter manually, but i need to create a login page where when the user enters the credentials, the application should get the his/her data from the tables by passing his username in the where clause of the query SELECT * FROM USER_ACC_TABLE WHERE USER = ?
How do I programmatically pass the parameters for a query in worklight adapters?
If you look at the docs, you will see that the invocation process includes a parameters key. In your case, I would use a JSON object as shown.
http://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.2.0/com.ibm.worklight.apiref.doc/html/refjavascript-client/html/WL.Client.html%23invokeProcedure
function invokeAdapter(USERNAME) {
var USERINFO = {username: USERNAME};
var invocationData = {
adapter: "USER_ACCT_TABLE",
procedure: "getUserData",
parameters:[USERINFO]
};
// DEFINE THE CALL BACK FUNCTIONS
var options = {
onSuccess: onSuccess,
onFailure: onFailure
};
WL.Client.invokeProcedure(invocationData, options);
}
In your adapter code, you would have something like the following:
var selectStatement = WL.Server.createSQLStatement("SELECT * FROM USER_ACC_TABLE WHERE USER = ?");
function getUserData(data) {
var USERNAME = data.username;
return WL.Server.invokeSQLStatement({
preparedStatement : selectStatement,
parameters : [USERNAME]
});
}
If I understand you correctly, you'd like to get the values that the user will input in the login form's text fields and use them in your adapter request?
Maybe the answer the following question will help: Passing parameters through HTTP Adapter?
While it explains it for HTTP adapter, the JavaScript part of getting the values should be the same.
Basically, you use the following the get the value from the input field. You could save it in a variable just as well:
parameters : [$('#element-name').val()]
Full example is available in the linked question.
For passing the value to your SQL query in a SQL adapter, the following answer by jnortey should help: IBM Worklight - Error while using variable in a SQL Adapter query, which is basically the same.
That's it. Now the '?' in the SQL query should get the parameter's value.

console.log in worklight procedure

my procdure in sql adapter is given below
var procedure1Statement = WL.Server.createSQLStatement("select * from userreg ");
function procedure1() {
var resp= WL.Server.invokeSQLStatement({
preparedStatement : procedure1Statement,
parameters : []
});
var a=resp.resultSet;
var name=new Array();
for(var i=0;i<a.length;i++){
name[i]=a[i].name;
}
//return (name);
//alert (name);
console.log( name.toString());
}
if i call this procedure can i display name values in browser console,
or if i use WL.logger.log() instead of console.log
You cannot use console.log in server-side code... you must have code in the client-side that will receive the response from this server-side code (that is - you must return it), and then you could use console.log (and other options) - in the client-side - to print the values to the console in your browser or LogCat or other tools...
What you can do in the case of adapter logging or debugging, is to use WL.Logger.warn or WL.Logger.error to print out to the Eclipse console.
See this question for more information on the above: IBM Worklight 6.0 - How to enable/view WL.Logger.debug in adapters?

IBM Worklight - Could not invoke the SQL adapter procedure for the insert query from the client side . What's wrong with my coding?

I'm getting a blank screen while running the code in the webpage. The adapter procedure alone is getting invoked correctly but I couldn't invoke it from my client side.I'm using Db2 database. Please help.
Here is my JavaScript code..
function loadDetails(x,y,z,a,b,c,d,e,f,g,h,i){
var x= document.getElementById("firstname").value;
var y= document.getElementById("lastname").value;
var z= document.getElementById("doorno").value;
var a= document.getElementById("streetname").value;
var b= document.getElementById("area").value;
var c= document.getElementById("zipcode").value;
var d= document.getElementById("landmark").value;
var e= document.getElementById("secques").value;
var f= document.getElementById("secans").value;
var g= document.getElementById("emailaddress").value;
var h= document.getElementById("username").value;
var i= document.getElementById("password").value;
var invocationData = {
adapter : 'DBAdapter',
procedure : 'addDBAdapter',
parameters : [x,y,z,a,b,c,d,e,f,g,h,i]
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : loadDetailsSuccess,
onFailure : loadDetailsFailure
});
}
function loadDetailsSuccess(){
alert("Registration Successfull. Please login to continue...");
window.location.href = 'login.html';
}
function loadDetailsFailure(){
WL.Logger.error("load data failure");
}
DBAdapter-impl.js
var addStatement = WL.Server.createSQLStatement("insert into CUSTOMER(FIRSTNAME,LASTNAME,DOORNO,AREA,STREETNAME,ZIPCODE,LANDMARK,SECQUES,SECANS,EMAILADDRESS,USERNAME,PASSWORD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)");
function addDBAdapter(x,y,z,a,b,c,d,e,f,g,h,i) {
return WL.Server.invokeSQLStatement({
preparedStatement : addStatement,
parameters : [x,y,z,a,b,c,d,e,f,g,h,i]
});
}
As eabe rightly so mention in the comments, and we've all missed it(!), Worklight is a Single Page Application and indeed window.location.href = 'login.html'; seems to be the culprit here.
See this related question on this subject matter that also contain solutions:
How to change between pages using Jquery Mobile in Worklight
Basically, you can use either jQuery's .load or jQuery Mobile's .changePage (or the equivalent of other libraries to do the same) in order to load the contents of another page, or "switch" to another. Doing what you do, you lost the Worklight "context" and nothing will work or display.
Also review this training material:
Building a multipage application