Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Library function from html with google.script.run

I implement library with Google App Script and I have some difficulties to call a function from library using google.script.run.

Here is the code of my Library :

Code.gs

function ShowSideBar() {
    var html = HtmlService.createTemplateFromFile('Index_librairie').evaluate()
        .setTitle('Console de gestion')
        .setWidth(300);
    SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
        .showSidebar(html);
}

function execution_appeler_par_html(){
  Logger.log("execution_appeler_par_html"); 

}

Index_librairie.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
    google.script.run.withSuccessHandler(work_off).execution_appeler_par_html(); 
    function work_off(e){
    alert(e);
    }
    </script>
  </head>
  <body>
    test de ouf
  </body>
</html>

Here is my Spreadsheet that use the Library : Code.gs

function onopen() {
  lbrairietestedouard.ShowSideBar();
}

Google.script.run does not reconize execution_appeler_par_html() function. I should use libraryname.execution_appeler_par_html() but this syntaxe doesn't work in configuration of google.script.run

like image 988
Edouard Delga Avatar asked Feb 22 '18 13:02

Edouard Delga


1 Answers

It seems that google.script.run can't look inside Objects or self-executing anonymous functions. In my case, putting any code inside an object or IIFE resulted in "is not a function" type of error being thrown in the console.

You can work around this by declaring a single function that will call nested methods inside libraries and objects.

.GS file

 function callLibraryFunction(func, args){

    var arr = func.split(".");
    
    var libName = arr[0];
    var libFunc = arr[1];
    
    args = args || [];
       
   return this[libName][libFunc].apply(this, args);

}

In JavaScript, every object behaves like an associative array of key-value pairs, including the global object that 'this' would be pointing to in this scenario. Although both 'libName' and 'libFunc' are of String type, we can still reference them inside the global object by using the above syntax. apply() simply calls the function on 'this', making the result available in global scope.

Here's how you call the library function from the client:

 google.script.run.callLibraryFunction("Library.libraryFunction", [5, 3]);

I don't claim this solution as my own - this is something I saw at Bruce McPherson's website a while back. You could come up with other ad-hoc solutions that may be more appropriate for your case, but I think this one is the most universal.

like image 86
Anton Dementiev Avatar answered Sep 28 '22 10:09

Anton Dementiev