How can I use google.script.run properly? - html

I've been recently working on a project that sends values to a google spreadsheet and
the failure handler always gives me an alert, am I doing something wrong?
By the way, here's the code:
MainGsFile.gs:
var Server = SpreadsheetApp.openByUrl("Spreadsheet Url");
//I know that's not the Spreadsheet Url
var Pages = Server.getSheets();
function doGet()
{
return HtmlService.createHtmlOutputFromFile("MainHtmlFile");
}
function SetCellValue(PageNum, Row, Column, Value)
{
Page[PageNum].getRange(Row, Column).setValue(Value);
}
function GetCellValue(PageNum, Row, Column)
{
return Page[PageNum].getRange(Row, Column).getValue();
}
MainHtmlFile.html:
<!DOCTYPE html>
<!--HTML Code-->
<html>
<body>
<button onclick="Test()">It's going to work</button>
</body>
</html>
<!--CSS Code-->
<style>
//Styles go here
</style>
<!--JavaScript Code-->
<script>
function Test()
{
google.script.run.withSuccessHandler(OnSuccess).withFailureHandler(OnFailure).SetCellValue(1, 1, 1, "true");
}
function OnSuccess()
{
alert("Yes");
}
function OnFailure()
{
alert("No");
}
</script>

Yes,
You can't pass mutiples arguments. Trick is to use object :
var obj = {};
obj.value = 1;
obj.value2 = 2;
obj.value3 = 3;
obj.bool = true;
google.script.run.withSuccessHandler(OnSuccess).withFailureHandler(OnFailure).SetCellValue(obj);

Related

Google Workspace, SpreadsheetApp.getUi().showSidebar causes "TransportError", with Error code = 10, Path = /wardeninit and google.script.run will fail

I'm trying to make a Google App script with this simple code below
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Test Menu')
.addItem('Test', 'doTest')
.addToUi();
}
function doTest() {
var htmlOutput = HtmlService
.createHtmlOutput('<p>Some Text</p>')
.setTitle('My title');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
The sidebar shows up correctly
[1]: https://i.stack.imgur.com/6QTR8.png
But i get this error in the chrome console:
message: "There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit"
name: "TransportError"
stack:"TransportError: There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit
at new Qo (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:200:381)
at Vo.w.Xc (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:208:372)
at Cf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:79:228)
at Bf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:472)
at xf.A (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:419)
at Cf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:79:228)
at Bf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:472)
at Vo. (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:207:159)
at An (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:165:294)
at Do (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:200:262)"
I have been make some Google App script before but just get this error recently.
What am I doing wrong?
Updated
Because of this "TransportError", any "google.script.run" script will fail.
If i update the code like this:
function doTest() {
var htmlOutput =
HtmlService.createHtmlOutputFromFile('Index');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
function doSomething() {
Logger.log('I was called!');
}
And the Index.html is
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onSuccess() {
console.log("onSuccess");
}
function onFailure(error) {
console.log("onFailure",error);
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).doSomething();
</script>
</head>
<body>
</body>
</html>
The onFailure will always be called and the error is empty.
Update 2
The problem with "google.script.run" script will fail.
only for google workspace account.
If I change to my personal gmail account and made the similar code, the problem does not happen.
I used your code like this:
html:(filename: ah3.html)
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onSuccess() {
console.log("onSuccess");
}
function onFailure(error) {
console.log("onFailure",error);
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).doSomething();
</script>
</head>
<body>
<div>Hello World</div>
</body>
</html>
gs:
function doTest() {
var htmlOutput = HtmlService.createHtmlOutputFromFile('ah3').setTitle('My title');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
function doSomething() {
Logger.log('I was called!');
}
It works for me.
If you look in the console you will see the onSuccess printed and if you look in executions you will see Sep 3, 2021, 10:16:03 PM Info I was called!

Using JSON files in html

I'm have trouble to understand how to use the data saved in a JSON file and load it in a html page Everything locally:
say this the JSON file :
{
"level1":{
"level1_1":{
"example": "test",
"example2":"123123"
},
"level1_2":{
"example": "test",
"example2":"123123"
}
},
"level2":{
"level2_1":{
"example": "test",
"example2":"123123"
},
"level2_2":{
"example": "test",
"example2":"123123"
}
}
}
And I want to be able to call the data from it, in and HTML file for example :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reading json</title>
<style>
</style>
</head>
<body>
<br>
file value :
<br>
<script>
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'config.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
function init() {
loadJSON(function(response) {
// Parse JSON string into object
var actual_JSON = JSON.parse(response);
});
}
</script>
</body>
I've got the script from this tutorial and still do get it run.
So my aim just to see after ** first value** data from the JSON file.
any idea how u guys do it ?
Here is a more elaborate answer.
First, let's parse the JSON into an object.
var actual_JSON = JSON.parse(response);
Second, transform the JSON object into a readable string.
var json_string = JSON.stringify(actual_JSON, undefined, 2);
Then, use the querySelector() function to select a DOM element. Note that #output means I want to select an ID attribute named output.
var output = document.querySelector("#output");
Then, I am adding by the JSON string to the DOM with the DOM innerHTML property. It will be added right after "file value".
output.innerHTML += json_string;
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reading json</title>
<style>
</style>
</head>
<body>
<br>
<div id="output">file value : </div>
<br>
<script>
// Starts.
init();
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'config.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
// init(xobj.responseText)
}
};
xobj.send(null);
}
function init() {
loadJSON(function(response) {
// Parse JSON string into object
var actual_JSON = JSON.parse(response);
// Transforms the JSON object into a readable string.
var json_string = JSON.stringify(actual_JSON, undefined, 2);
// Select <br> tag.
var output = document.querySelector("#output");
// Adds it to the DOM.
output.innerHTML += json_string;
});
}
</script>
</body>
You have to add some id attribute in html, then select based on that id and loop the json data and insert like this
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reading json</title>
<style>
</style>
</head>
<body>
<div id="json_result"></div>
<script>
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'config.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
function init() {
loadJSON(function(response) {
// Parse JSON string into object
var actual_JSON = JSON.parse(response);
for (var key in actual_JSON) {
var innerkey = actual_JSON[key];
for (var inner in innerkey) {
document.getElementById('json_result').innerHTML += 'Example: '+innerkey[inner]['example']+'<br>';
document.getElementById('json_result').innerHTML += 'Example2: '+innerkey[inner]['example2']+'<br>';
}
}
});
}
init();
</script>
</body>
This stack overflow question will guide you well

JS not calling function

Here is my calling html code
<!DOCTYPE html>
<html>
<head>
<title>Display Card Type</title>
</head>
<script src='Card.js'; ></script>
<body>
<script>
var card = new myCardType();
var value = new myCardType();
card.setCard('I am a club');
value.setFace('I am an Ace');
card.showSuit();
value.showFace();
</script>
</body>
</html>
And here is the separate function (saved in same folder).
function myCardType(){
this.suit = suit;
this.showSuit = function(){
alert(this.suit);
}
this.face = value;
this.showFace = function() {
alert(this.face);
}
this.setCard = function (newSuit) {
this.suit = newSuit;
}
this.setFace = function (newValue) {
this.face = newValue;
}
}
Spent ages reviewing this but just cannot see what is going on, grateful for any clues.

Contents of a spreadsheet are not displayed in the deployed Apps Script webapp

I've tried to do an example of the 3rd tutorial on this ctrlq page, in which we display the content of a spreadsheet on a web page. Here are my files which I simply entered - I didn't activate anything, I just did Publish -> Deploy as web app
I expect to see all of the spreadsheet's values, but instead nothing is shown:
Code.gs
function doGet() {
var html = HtmlService.createTemplateFromFile("index").evaluate();
html.setTitle("Dynamic Webpage");
return html;
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.getContent();
}
function getData(){
var sheet = SpreadsheetApp.openById("1k_kj98U__0Bk44gh0qRFpaVx0ru3sN1pSPGiMQwimxo").getSheets()[0];
return sheet.getDataRange().getValues();
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<?!= include('script_js'); ?>
<body>
<div id="data"></div>
</body>
</html>
script_js.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
window.onload = function(){
google.script.run.withSuccessHandler(showData).getData();
}
function showData(data){
var html = "";
for (var i=0; i<data.length; i++) {
html += "<br>" + data[i].join(":");
}
document.getElementById("data").innerHTML = html;
}
</script>
</body>
</html>
Link to the script project
EDIT as #tehhowch pointed out his answer is the correct solution here.
For your case you should make these changes, getData():
function getData(){
var sheet = SpreadsheetApp.openById("1k_kj98U__0Bk44gh0qRFpaVx0ru3sN1pSPGiMQwimxo").getSheets()[0];
return JSON.stringify(sheet.getDataRange().getValues()); // return value as Json
}
And showData(data):
function showData(data) {
var arr = JSON.parse(data);
var html = "";
for (var i=0; i < arr.length; i++) {
html += "<br>" + arr[i].join(":");
}
document.getElementById("data").innerHTML = html;
}

google.script.run is returning undefined. How do I fix it?

I'm trying to get an array from a spreadsheet and use it to populate a dropdown. Here is my code
code.gs
function doGet() {
var page = HtmlService.createTemplateFromFile('Index');
return page.evaluate()
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function getArrayList(){
var ss = SpreadsheetApp.openById("1EjRFAYiMBw5BuNhFJRUVG4MpUjIIy8Oey5JLyiYxj3c");
var sheet = ss.getSheetByName("Nomes");
var values = sheet.getDataRange().getValues();
var array = [];
for each (var item in values){
array.push(item[0]);
}
return array
}
Index.html
<!DOCTYPE html>
<html>
<?!= include('jQuery'); ?>
<div class="demo" >
<form id="myForm">
<select id="selectNumber">
<option>Choose a number</option>
</select>
</form>
<?!= include('JavaScript'); ?>
</div>
</html>
JavaScript.html
<script>
var options = google.script.run.getArrayList();
console.log(options);
$('#selectNumber').empty();
$.each(options, function(i, p) {
$('#selectNumber').append($('<option></option>').val(p).html(p));
});
</script>
jQuery.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
If instead of using var options = google.script.run.getArrayList(); on the JavaScript.html file, I pass a literal array var options = ["1","2","3"]; my code works like a charm.
I know that the problem is that google.script.run is returning Undefined, but I don´t know what I´m doing wrong. Can someone please help me?
Is this useful for you?
google.script.run.function() doesn't return values. So options of var options = google.script.run.getArrayList(); is Undefined. Use withSuccessHandler() to get the returned values from getArrayList(). Below is the updated JavaScript.html.
<script>
google.script.run.withSuccessHandler(sample).getArrayList();
function sample(options) {
$('#selectNumber').empty();
$.each(options, function(i, p) {
$('#selectNumber').append($('<option></option>').val(p).html(p));
});
}
</script>
values is an array of arrays. To get all of the data you need to do something like:
var a=[];
for(var i=0;i<values.length;i++)
{
for(var j=0;j<values[0].length;j++)
{
a.push(values[i][j]);
}
}
or just return values