Search code examples
cordovaionic3inappbrowser

Execute typescript functions called from executeScript from InAppBrowser


I am implementing ionic cordova InAppBrowser functionality, in which I have to call a function written outside the InAppBrowser "loadstop" event. What I want here is to call a callBack() function soon after executing loadstop event.

My dummy code is:

this.browser.on("loadstop").subscribe((event)=>{
this.browser.executeScript({code: if(document.getElementByID("ID").length > 1){function callBack();}})
});

callback(){
this.browser.hide();
}

Solution

  • The code you inject via executeScript() is executed in the scope of the InappBrowser Webview, not the Cordova app Webview, so has no visibility of functions in your Cordova app. Also note that the code argument passed to executeScript() must be stringified Javascript because it will be passed to the InappBrowser Webview via the native bridge.

    Therefore there are 2 ways you can achieve your callback:

    Firstly, because the condition whether to invoke your callback can be evaluated synchronously in the context of the InappBrowser Webview, you can synchronously return the result of your DOM query using current npm releases of cordova-plugin-inappbrowser, for example:

    callBack(){
        console.log("Typescript callback has been called");
        this.browser.hide();
    }
    
    this.browser.on("loadstop").subscribe((event)=>{
        this.browser.executeScript(
            {
                code: 'document.getElementByID("ID").length > 1;'
            },
            function(values){
                var result = values[0];
                if(result){
                    callBack();
                }
            }
        );
    });
    

    However if the result of your condition needed to be returned asynchronously, the above method would not work. Instead you could use the postMessage API implementation, added to cordova-plugin-inappbrowser for Android & iOS platforms by this PR. It's not yet been released in a version to npm, so you'd need to install the master branch of the plugin directly from the Github repo:

    cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser
    

    You'd then use it like this:

    callBack(){
        console.log("Typescript callback has been called");
        this.browser.hide();
    }
    
    this.browser.on("message").subscribe((event)=>{
        if(event.data.action === "callBack"){
            callBack();
        }
    });
    
    this.browser.on("loadstop").subscribe((event)=>{
        this.browser.executeScript(
            {
                code: '\
                    setTimeout(function(){\
                        if(document.getElementByID("ID").length > 1){\
                            webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify({\
                                action: "callBack"\
                            }));\
                        } \
                    }, 250);\
                '
            }
        );
    });