0

I am attempting to convert an android app to a website using GWT. This was just an idea for a future-project.

What I want to do is mimic the Cursor function. I can do that just fine creating a class and just mimicking the functions I want to use.

But here is my issue: My UI finishes its code before the Cursor is fully initialized.

Here's how it works so far. I have the following code in my onModuleLoad, in my entrypoint:

Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
    label.setText("Column-count: "+cursor.getColumnCount());

This outputs 0, because the entrypoint does not wait for my cursor-class to fully initialize.

My retrieveData method is here:

Cursor retrieveData(String query){
    return new Cursor(query);
}

And my constructor in the Cursor-class is here

Cursor(String sql) {
    greetingService = GWT.create(GreetingService.class);
    columns = new ArrayList<>();
    rows = new ArrayList<>();
    currentPosition = -1;
    
    greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
        @Override
        public void onFailure(Throwable caught) {}
        
        @Override
        public void onSuccess(List<List<String>> result) {
            if (!result.isEmpty()) {
                columns = result.get(0);
                if (result.size() > 1) {
                    rows.addAll(result.subList(1, result.size()));
                }
            }
        }
    });
}

I have tried stopping the UI-activity with a while-loop waiting for a boolean to go from true to false (set to false in the onSuccess of the AsyncCallback), but the UI-activity is just locked and the site crashes.

Does somebody have a solution here?

Mr. Nielzom
  • 137
  • 1
  • 10
  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – ᴇʟᴇvᴀтᴇ Sep 17 '20 at 16:24

3 Answers3

1

Use Promises.

If you are making a HTTP request to a backend service, you could use the Fetch API, which uses promises, though convenient rather than necessary.

GWT's Elemental2 library provides bindings to the promises and fetch API's. For example:

DomGlobal.fetch("http://example.com/bar?x=5")
.then(response -> response.json())
.then(jsonData -> {
    parseDataAndUpdateUI(jsonData);
    return null;
});
Rob Newton
  • 910
  • 7
  • 15
1

For doing those server calls you can also use domino-rest which already have an implementation for android domino-rest-android and to make several calls and wait for them to finish you could try using domino-aggregator

with domino-aggregator you can do something like the following

ContextAggregator.ContextWait<String> waitForString = ContextAggregator.ContextWait.create();
ContextAggregator.ContextWait<Integer> waitForInteger = ContextAggregator.ContextWait.create();

ContextAggregator.waitFor(waitForString, waitForInteger)
        .onReady(() -> {
            //will be called when both waits are resolved.
        });

waitForString.complete("some string");
waitForInteger.complete(5);

so simply you could make a waiting context for the server call, meanwhile move the initialization of the UI into the onReady method.

Ahmad Bawaneh
  • 716
  • 5
  • 17
1

Both answers before point out the solution to your problem. And they show two more - and I think modern - ways to get data from the server.

Your problem with the following code is:

Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
label.setText("Column-count: "+cursor.getColumnCount());

that 'retrieveData' calls the server but does not wait until the server returns. That's the nature of asynchronous calls.

Move 'label.setText("Column-count: "+cursor.getColumnCount());' into the 'onSuccess'-method and it will work.

Cursor(String sql) {
    greetingService = GWT.create(GreetingService.class);
    columns = new ArrayList<>();
    rows = new ArrayList<>();
    currentPosition = -1;
    
    greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
        @Override
        public void onFailure(Throwable caught) {}
        
        @Override
        public void onSuccess(List<List<String>> result) {
            if (!result.isEmpty()) {
                columns = result.get(0);
                if (result.size() > 1) {
                    rows.addAll(result.subList(1, result.size()));
                }
            }
            label.setText("Column-count: "+cursor.getColumnCount());
        }
    });
}
El Hoss
  • 3,588
  • 2
  • 15
  • 23