MKHC
MKHC

Reputation: 459

Why are busy indicators not displayed when sending requests?

I have some slow OData calls which need to present some sort of visual indicator to the user that something is happening.

I've read the API reference and seen functions like attachRequestSent(), setBusy(), BusyDialog, BusyIndicator, etc.

I tried using them accordingly but did not work for me. The problem seems to be oModel.create causing the whole app to hang while it executes. No loading indicators or anything can run since the app is frozen until the create function has returned.


Edit: I have set up an asynchronous batch read OData call. I have then wrapped the code for handling the received data in a function and called that function inside the success function in the batch call.
This works; the view loads and I see a busy indicator before the fields are populated with the data

oModel.submitBatch(/*fnSuccess*/);

Is this a good way to do it, or is there a better way which is more standard?

Upvotes: 2

Views: 7641

Answers (3)

Boghyon Hoffmann
Boghyon Hoffmann

Reputation: 18044

The main problem seems to be oModel.create causing the whole app to hang while it executes. No loading indicators or anything can run since the app is frozen until the create function has returned.

Sounds like you've been using the now-deprecated sap.ui.model.odata.ODataModel the whole time, which sends mostly synchronous XHRs. Synchronous XHRs block the main thread (== UI thread) until the browser receives the response. The browser isn't then able to update the DOM to display the busy indicator during the round trip.

If anyone reading this has the same issue, please migrate to the newer equivalent model: sap/ui/model/odata/v2/ODataModel. It sends only asynchronous requests (AJAX), allowing the UI thread to handle other tasks (such as adding the busy indicator to the DOM) while the browser waits for the response.

Upvotes: 0

Tiago A.
Tiago A.

Reputation: 1482

Before the Odata call, display the busy indicator (locks the entire app screen). with

sap.ui.core.BusyIndicator.show(0);

Then, in both the success and failure handlers of the odata call, hide it with

sap.ui.core.BusyIndicator.hide();

It does not work with implicit calls (when for instance you bind to an odata model), for this you can use the request sent events, but the idea is the same.

Edit: You also need to give a small delay to allow the indicator to appear, then use setTimeout to call your odata after a small delay.

doStuffWithIndicator: function(){
        sap.ui.core.BusyIndicator.show(0);
        setTimeout(function(){
            doStuff();
            sap.ui.core.BusyIndicator.hide();
        }, 20);

    },

Upvotes: 3

dotchuZ
dotchuZ

Reputation: 2641

checkout this thread: SAPUI5 Wait for an Deferred-Object // wait for .done() function

Javascript is asynchrone, this means the code will be processed further no matter if you make an call (which might take longer). Therefore before calling an OData Service you need to tell your JS to wait for it (make it synchrone) via an deferred object.

Upvotes: 0

Related Questions