B4J Question ABMaterial JavaScript code

walterf25

Expert
Licensed User
Longtime User
Hi all, how would I run the following javascript code in a ABMaterial web app:

JavaScript:
var api = dtpweb.DTPWeb.getInstance();

async function updatePrinterList() {
    var printerElements = document.getElementById("select-printlist");

    if (api) {
        var printers = await api.getPrinters({ onlyLocal: false });
        printerElements.innerHTML = "";
        if (printers instanceof Array && printers.length > 0) {
            for (var i = 0; i < printers.length; i++) {
                var item = printers[i];
                var name = item.hostname && item.type !== 1 ? item.name + "@" + item.hostname : item.name;
                var value = item.ip ? item.name + "@" + item.ip : item.name;
                printerElements.options.add(new Option(name, value));
            }
        } else {
            printerElements.options.add(new Option("Text", ""));
        }
        onPrinterChanged();
    }
}

I have tried the Following without any success:
B4X:
            Dim jsval As String = $"var api = dtpweb.DTPWeb.getInstance();
            var printers = await api.getPrinters({ onlyLocal: false });
            "$
            page.ws.Eval(jsval, Null)
            page.ws.Flush

I receive the following error in the console

VM3730:4 Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
at new Function (<anonymous>)
at b4j_eval (core.4.97.min.js:97:9)
at x.<anonymous> (core.4.97.min.js:112:418)
at x.dispatchEvent (core.4.97.min.js:288:112)
at WebSocket.<anonymous> (core.4.97.min.js:214:27)

Any ideas?
Walter
 

alwaysbusy

Expert
Licensed User
Longtime User
You can not use async methods with ws.eval. You will have to rewrite the method as a classic promise with .then() and raise an event.
I don't have this dtweb library to test, but it should be something like this:

B4X:
Public Sub GetPrinters()
    dim Script as String = $"var api = dtpweb.DTPWeb.getInstance();
        api.getPrinters({ onlyLocal: false }).then(function(printers) {
            var res = {};
            if (printers instanceof Array && printers.length > 0) {
                for (var i = 0; i < printers.length; i++) {
                    var item = printers[i];
                    var name = item.hostname && item.type !== 1 ? item.name + "@" + item.hostname : item.name;
                    var value = item.ip ? item.name + "@" + item.ip : item.name; 
                    // check in the browser console if it gets to here      
                    console.log(name);
                    console.log(value);
                    res[name] = value;
                }
            }
            b4j_raiseEvent("got_printers",res);
        });"$
    page.ws.eval(Script, null)
    page.ws.flush
End Sub

Public Sub got_printers(Params As Map) ' must have an _ in the sub name and a single parameter Map
     For each key as string in Params.Keys
          log(key);
          log(Params.Get(key));
      Next
End Sub

Alwaysbusy
 
Last edited:
Upvote 0
Top