can I invoke a procedure synchronously? - ibm-mobilefirst

This might sound a bit crazy but is there a way to call a procedure synchronously?
I am using MobileFirst Platform Foundation 7.1 and I am writing an app in javascript for the browser. I usually call my javascript adapter by:
WL.Client.invokeProcedure({
adapter: 'MyAdapter',
procedure: 'myProcedureName',
parameters: []
}).then(function(res) {
...
});
But in this particular case I need to open another window after getting some data from the server. Since browsers will block windows when they come from async ajax my new windows does never open.
A way to solve this would be to do the ajax request sync. Is this possible with WL.Client apis? Is there a way for constructing the request manually so I can set the sync ajax flag by myself?
PS: in my case doing sync ajax request would work nice since I show a "Loading ..." view on top of everything to prevent user interaction while the request is being done.

WL.Client.connect() does not support .then. Additionally, starting 7.0 you should use the REST API method WLResourceRequest: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-1/foundation/server-side-development-category/
Lastly, you could just put the second request in the onSuccess callback of the first...

Related

Is it a best practice to make setInterval every some seconds to re update axios request to update displayed data in vue project? [duplicate]

hi
I want to build a control panel for a web art application that needs to run in fullscreen, so all this panel, that controls stuff like colors and speed values, have to be located at a different window.
My idea is to have a database storing all these values and when I make a change in the control panel window the corresponding variable in the application window gets updated too. So, it's basically a real-time update that I could do with AJAX setting a interval to keep checking for changes BUT my problem is: I can't wait 30 seconds or so for the update to happen and I guess a every-1-second AJAX request would be impossible.
Final question: is there a way to create a sort of a listener to changes in the database and fire the update event in the main application only immediately after I change some value in the control panel? Does Angular or another framework have this capability?
(Sorry for the long explanation, but I hope my question is clearer by offering the context [: )
A web socket powered application would have this benefit. This carries a bit more complexity on the back end, but has the benefit of making your application as close to real-time as can be reasonably expected.
The Mozilla Development Network has some good documentation on websockets.
On the front end, the WebSocket object should work for you on most modern browsers.
I'm not sure what your back end is written in, but Socket.IO for Node.js and Tornado for Python will make your applications web-socket capable
If one window is opening the other windows via JavaScript, you can keep the reference to the opened window and use otherWindow.postMessage to pass messages across
"Parent" window looks like
// set up to receive messages
window.addEventListener('message', function (e) {
if (e.origin !== 'http://my.url')
return; // ignore unknown source
console.log(e.message);
});
// set up to send messages
var otherWindow = window.open('/foo', '_blank');
otherWindow.postMessage('hello world', 'http://my.url');
"Child" windows look similar
// same setup to recieve
// ...
// set up to send
var otherWindow = window.opener;
// ... same as before
For the realtime I would recommend using a library like socket.io or using a database like firebase.
For the fullscreen I would recommend using a library like angular-screenfull
i use https://pushjs.io/, had exactly the same problem and this is a really simple solution for your problem. It is capable of sending and listening to events without any database interference.

how can i call a worklight's SQL adapter on the load event of a html page

I have an existing SQL adapter used to get some data from the DB server, a simple query that returns a language.
I want to call it from an HTML page, to display the page in the language returned from the adapter.
I'm trying to call it before the dojoConfig object is created because it sets the locale, that then it's used by dojo to do the internationalization work. Is there a way to call the adapter synchronously so it executes before the dojo configuration happens? I mean to catch either the success or failure response before a dojoConfig object is created.
How could i invoke it?
Worklight APIs can only be used once wlCommonInit has been called.
If you can delay/postpone/set dojoConfig on the success callback of the adapter call, then this may be your way out of the problem you have encountered.

IBM Worklight 6.1.0.1, trouble with 2 adapters based authentication

I am facing to a trouble with 2 adapters based authentication. My app is agenda (hybrid app). All adapter's functions must be protected by security.
my app uses adapters based authentication, like written in samples on DeveloperWorks.
My first adapter (loginAdapter) is dedicated for login (beginning of the mobile app). I developed a handler (handlerLogin, mobile side) with methods isCustomResponse, handlechallenge, etc.. This adapter works.
This adapter allows to get a userId from login and password.
As soon as connected, the user can download his agenda. The mobile calls an other adapter based auth (calendarAdapter). I have an other handler (handlerCalendar) with methods (isCustomResponse, handlechallenge).
When the mobile calls the method getCalendarData (protected method, CalendarAdapter), the server detects that the user is not registered for this adapter, that is why the server send an error (structure authrequired + errorMessage) via the function onAuthRequired.
At this step, all works fine.
Actually, the trouble comes from, that, the first handler (handlerLogin) catches this error, whereas it schould be the second handler (handlerCalendar).
Given that it is catched by the handlerLogin, isCustomResponse and handlechallenge are called, and I do not have the expected result ! I do not know why.
Why it is not catched by the handlerCalendar ?
I verified my code, variable's names, files, etc.. All things are ok.
For informations, I first declared the handlerLogin before the CalendarLogin.
Do you have any ideas, suggestions ??
Thank you in advance
It looks like you used the same realm.
The isCustomResponse function job is to find out if this challenge-handler should take care of this specific request. If you use the same realm for both adapters then the 2 challenge-handlers will react to it.

Adapter procedure call, reporting an authentication failure

Client code attempts to invoke adapter. This triggers authentication to the appropriate realm. It is possible that the user does not have suitable credentials and eventually wants to stop trying. I can provide a "Give Up" button, and we can use the challegeHandler to tell Worklight to stop the authentication effort like this:
this.challengeHandler.submitFailure();
This works to the extent that the login attempt terminates, but it seems that code calling the adapter gets no callback and hence any Deferred objects that might be waiting for resolution are left in limbo.
The question is whether we can arrange to get the authentication failure back to the caller of the adapter procedure?
I have been informed of a workaround to this issue whereby you call:
challengeHandler.activeRequest.onUnresponsiveHost()
Before actually calling:
challengeHandler.submitFailure()
This will trigger the failure and reject the deferred as intended.
This is a workaround though so it might not work in future versions. I am going to raise a request for enhancement (link pending) and I would appreciate it if you could vote it up as well to ensure this functionality is available in the future.
First of all, submitFailure() will not call adapter. It will notify client side framework that authentication has failed completely so the framework will dispose of any stored requests that are waiting for authentication to finish.
If you want to wipe user identity on a server side you have two options
create an adapter procedure which doesn't require authentication and call WL.Server.setActiveUser("realm-name",null). This will terminate any userIdentity.
call WL.Client.logout("realm-name") in your app

jQuery Ajax abort and new request in quick succession

I have a mobile app, which makes a
JqXHR = $.ajax({
url: 'url',
data: null,
async: true,
cache: false,
dataType: 'json',
type: 'GET',
crossDomain: true,
timeout: 63000,
success: function(data, textStatus, jqXHR) {},
error: function(jqXHR, textStatus, errorThrown) {}
});
request. It waits for 63 seconds (the PHP backend CAN run for ~62 seconds) for user interaction at the other end. Now, if in the meanwhile I decide to abort this request, then i call JqXHR.abort(). In the error handler I already handle/differentiate between real errors and aborts, that works. Right after the abort, I want to send an other API call to the server to tie the loose ends and make sure my cancel request is logged.
And there is the problem. Even tho I abort() the first request, the PHP script is still running on the server, which wouldn't be a problem if it also executed the second request, which would make it to stop and die(). But it is not happening. The second request is not happening until the first finishes.
Any ideas?
jQuery 1.8.2, jQuery Mobile 1.2.0, PhoneGap 2.0.0 and 2.1.0, Apache 2, Linux, PHP 5.3
Some information to: Parallel-Ajax vs Apache-Session locking
Session data is usually stored after your script terminated, but as session data is locked to prevent concurrent writes only one script may operate on a session at any time.
When e.g. using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as possible.
So you can use sessions in ajax scripts with
session_start(); (maybe handled automatically) followed immediately (soon as possible) by session_write_close();
session_write_close(); will "end" the current session and store the session data.
But: session_id() will still deliver the correct (current) PHPSESSID so you're able to re obtain write access to the current session by simply doing session_start() again at any time you need it.
I use it this way in all my ajax scripts to implement session handling and allowing parallel request
It seems I ran into the good old PHP sessions vs. AJAX requests issue. Actually my boss found out about this issue by googling some expressions i never thought of. I am using Zend framework in the back-end, and it automatically starts a session namespace, so in my API controller's preDispatch() method I had to put in a #session_write_close(); line, and as if by magic, it works like a charm.
Thanks Arun for your quick reply, it is most appretiated.
So, in short: If you use Zend Framework or session_autostart or other means of starting sessions, they won't fly with parallel AJAX requests.
The abort method will not terminate the server process, it will just terminate the client side wait for the server response.