Variable returns undefined - javascript

I am receiving undefined for the variable called: names
Any help on why it is not displaying the results. It will display in the logger but not on the index.html or the web side after search is pressed.
code:
// var names =[]; //I tried using a global variable but with no luck
function SearchFiles(searchTerm) {
var searchFor = "title contains '" + searchTerm + "'";
var owneris = "and 'Email#email.com' in Owners";
var names = [];
var fileIds = [];
Logger.log(searchFor + " " + owneris);
var files = DriveApp.searchFiles(searchFor + " " + owneris);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId(); // To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i = 0; i < names.length; i++) {
//this is showing in the Logger
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
}
function returnNames(names) {
return '<h3><b>returnNames has ran.!</b></h3> <br>' + names; // Why does this names variable return undefined???
}
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate()
.setTitle('Search Drive')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(searchTerm) {
var resultToReturn;
Logger.log('processForm was called! ' + searchTerm);
resultToReturn = SearchFiles(searchTerm);
Logger.log('resultToReturn: ' + resultToReturn)
// shows as undefined in the logger
return resultToReturn;
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function displayMessage() {
var searchTerm;
searchTerm = document.getElementById('idSrchTerm').value;
console.log('searchTerm: ' + searchTerm);
google.script.run.processForm(searchTerm);
google.script.run.withSuccessHandler(handleResults).returnNames();
}
function handleResults(searchTerm) {
console.log('Handle Results was called! ');
document.writeln(searchTerm);
}
</script>
</head>
<body>
<input type="text" id="idSrchTerm" name="search">
<input type="button" value="submitButton" name="submitButton" onclick="displayMessage()" />
</body>
</html>

I think you're doing it in the wrong way. It will work if you return returnNames(names) at the end of SearchFiles and you just call google.script.run.withSuccessHandler(handleResults).processForm(searchTerm); inside your index.html like this:
Code.gs
function SearchFiles(searchTerm) {
var searchFor = "title contains '" + searchTerm + "'";
var owneris = "and 'Email#email.com' in Owners";
var names = [];
var fileIds = [];
Logger.log(searchFor + " " + owneris);
//Logger.log(searchFor);
var files = DriveApp.searchFiles(searchFor + " " + owneris);
//var files = DriveApp.searchFiles(searchFor);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId(); // To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i = 0; i < names.length; i++) {
//this is showing in the Logger
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
return returnNames(names); // Here call directly returnNames and get the wanted result
}
function returnNames(names) {
var result = '<h3><b>returnNames has ran.!</b></h3> <br>'; // + names; // Why does this names variable return undefined???
result += '<div>names.length = '+names.length+'</div>';
for(var i=0; i<names.length; i++) {
result += '<div>'+names[i]+'</div>';
}
return result;
}
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate()
.setTitle('Search Drive')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(searchTerm) {
var resultToReturn;
Logger.log('processForm was called! ' + searchTerm);
resultToReturn = SearchFiles(searchTerm);
Logger.log('resultToReturn: ' + resultToReturn)
// shows as undefined in the logger
return resultToReturn;
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function displayMessage() {
var searchTerm;
searchTerm = document.getElementById('idSrchTerm').value;
console.log('searchTerm: ' + searchTerm);
//google.script.run.processForm(searchTerm);
//google.script.run.withSuccessHandler(handleResults).returnNames();
google.script.run.withSuccessHandler(handleResults).processForm(searchTerm);
}
function handleResults(searchTerm) {
console.log('Handle Results was called! ');
document.writeln(searchTerm);
}
</script>
</head>
<body>
<input type="text" id="idSrchTerm" name="search">
<input type="button" value="submitButton" name="submitButton" onclick="displayMessage()" />
</body>
</html>
The result screenshot of my files using the term "test":

You can try it this way to pass around names to your google script.
In SearchFiles(searchTerm) you return names (which can be either blank array or valued array with names in it).
// var names =[]; //I tried using a global variable but with no luck
var Logger = {
log: function(){
console.log(arguments[0]);
}
};
function SearchFiles(searchTerm) {
var searchFor = "title contains '" + searchTerm + "'";
var owneris = "and 'Email#email.com' in Owners";
var names = ["file1","file2","file3"];
var fileIds = [];
Logger.log(searchFor + " " + owneris);
/* var files = DriveApp.searchFiles(searchFor + " " + owneris);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId(); // To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}*/
for (var i = 0; i < names.length; i++) {
//this is showing in the Logger
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
return names;
}
function returnNames(names) {
return '<h3><b>returnNames has ran.!</b></h3> <br>' + names; // Why does this names variable return undefined???
}
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate()
.setTitle('Search Drive')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(searchTerm) {
var resultToReturn;
Logger.log('processForm was called! ' + searchTerm);
resultToReturn = SearchFiles(searchTerm);
Logger.log('resultToReturn: ' + resultToReturn)
// shows as undefined in the logger
return resultToReturn;
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function displayMessage() {
var searchTerm;
searchTerm = "DUMMY TEXT";//document.getElementById('idSrchTerm').value;
console.log('searchTerm: ' + searchTerm);
//google.script.run.processForm(searchTerm);
//google.script.run
//.withSuccessHandler(handleResults)
//.returnNames(google.script.run.processForm(searchTerm));
processForm(searchTerm);
}
function handleResults(searchTerm) {
console.log('Handle Results was called! ');
document.writeln(searchTerm);
}
</script>
</head>
<body>
<input type="text" id="idSrchTerm" name="search">
<input type="button" value="submitButton" name="submitButton" onclick="displayMessage()" />
</body>
</html>

Related

Select one Particular sheet instead of listing all the sheets. Google app script, Code

I got this code from here : Display Spreadsheet Data to HTML Table
thanks to the great work of Cooper.
function htmlSpreadsheet(ssO) {
var br='<br />';
var s='';
var hdrRows=1;
var ss=SpreadsheetApp.openById(ssO.id);
var sht=ss.getSheetByName(ssO.name);
var rng=sht.getDataRange();
var rngA=rng.getValues();
s+='<table>';
for(var i=0;i<rngA.length;i++)
{
s+='<tr>';
for(var j=0;j<rngA[i].length;j++)
{
if(i<hdrRows)
{
s+='<th id="cell' + i + j + '">' + '<input id="txt' + i + j + '" type="text" value="' + rngA[i][j] + '" size="20" onChange="updateSS(' + i + ',' + j + ');" />' + '</th>';
}
else
{
s+='<td id="cell' + i + j + '">' + '<input id="txt' + i + j + '" type="text" value="' + rngA[i][j] + '" size="20" onChange="updateSS(' + i + ',' + j + ');" />' + '</th>';
}
}
s+='</tr>';
}
s+='</table>';
s+='</body></html>';
var namehl=Utilities.formatString('<h1>%s</h1>', ss.getName());
var shnamehl=Utilities.formatString('<h2>%s</h2>', sht.getName());
var opO={hl:s,name:namehl,shname:shnamehl};
return opO;
}
function updateSpreadsheet(updObj) {
var i=updObj.rowIndex;
var j=updObj.colIndex;
var value=updObj.value;
var ss=SpreadsheetApp.openById(updObj.id);
var sht=ss.getSheetByName(updObj.name);
var rng=sht.getDataRange();
var rngA=rng.getValues();
rngA[i][j]=value;
rng.setValues(rngA);
var data = {'message':'Cell[' + Number(i + 1) + '][' + Number(j + 1) + '] Has been updated', 'ridx': i, 'cidx': j};
return data;
}
function doGet() {
var userInterface=HtmlService.createHtmlOutputFromFile('htmlss').setWidth(1000).setHeight(450);
return userInterface.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function getAllSpreadSheets() {
var files=DriveApp.getFilesByType(MimeType.GOOGLE_SHEETS);
var s = '';
var vA=[['Select Spreadsheet',0]];
while(files.hasNext())
{
var file = files.next();
var fileName=file.getName();
var fileId=file.getId();
vA.push([fileName,fileId]);
}
//return vA;
return {array:vA,type:'sel1'};
}
//working on this function right now 2017/11/08
function getAllSheets(ssO) {
var ss=SpreadsheetApp.openById(ssO.id);
var allSheets=ss.getSheets();
var vA=[['Select Sheet']];
for(var i=0;i<allSheets.length;i++)
{
var name=allSheets[i].getName();
vA.push([name]);
}
return {array:vA,type:'sel2'};
}
What I am trying to do is on a Single sheet. That is I don't want to browse all sheets and select among them~
I have tried modifying this code
function getAllSpreadSheets() {
var files=DriveApp.getFilesByType(MimeType.GOOGLE_SHEETS);
var s = '';
// var vA=[['Select Spreadsheet',0]];
while(files.hasNext())
{
// var file = files.next();
var fileName=file.getName();
var fileId=file.getId();
vA.push([fileName,fileId]);
}
//return vA;
return {array:vA,type:'sel1'};
}
I have used sheet Id instead of file.getId(), But It just don't work.
Please help me.
Change:
var files = DriveApp.getFilesByType(MimeType.GOOGLE_SHEETS)
To getFileById():
var file = DriveApp.getFileById("sheet Id");
Then remove the loop:
function getSingleSpreadSheet() {
var file = DriveApp.getFileById("sheet Id")
var fileName = file.getName()
var fileId = file.getId()
var vA = []
vA.push([fileName, fileId])
return {
array: vA,
type:'sel1'
}
}

How to parse XML using AJAX in html?

I'm trying to parse XML by using AJAX. However there were a few errors which i got saying my "html is not defined"
Basically what I want to do is to parse a specific amount of data from my XML codes and display it using HTML webpage .
The below is the list of bugs in console when I tried to run the script
at displayCountrylist (test2.html:136)
at handleStatusSuccess (test2.html:61)
at readyStateChangeHandler (test2.html:32)
at XMLHttpRequest.xhttp.onreadystatechange (test2.html:16)
I tried to do everything to debug but still failed. Any one help please?
<html>
<script>
function makeAjaxQueryCountrylist()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
readyStateChangeHandler(xhttp);
};
xhttp.open("GET", "A3_CtryData_dtd_Sample.xml", true);
xhttp.send();
}
function readyStateChangeHandler(xhttp)
{
if (xhttp.readyState == 4)
{
if(xhttp.status == 200)
{
handleStatusSuccess(xhttp);
}else
{
handleStatusFailure(xhttp);
}
}
}
function handleStatusFailure(xhttp){
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}
function handleStatusSuccess(xhttp)
{
var xml = xhttp.responseXML;
var countrylistObj = parseXMLCountrylist(xml);
displayCountrylist(countrylistObj);
}
function parseXMLCountrylist(xml)
{
var countrylistObj = {};
var countrylistElement = xml.getElementsByTagName("CountryList")[0];
var recordElementList = countrylistElement.getElementsByTagName("CountryRecord");
countrylistObj.recordList = parseRecordElementList(recordElementList);
return countrylistObj;
}
function parseRecordElementList(recordElementList)
{
var recordList = [];
for(var i=0; i < recordElementList.length; i++)
{
var recordElement = recordElementList[i];
var recordObj = parseRecordElement(recordElement);
recordList.push(recordObj);
}
return recordList;
}
function parseRecordElement(recordElement)
{
var recordObj = {};
var countrycodeElement = recordElement.getElementsByTagName("country-code")[0];
recordObj.countrycode = Number(countrycodeElement.textContent);
var nameElement = recordElement.getElementsByTagName("name")[0];
recordObj.name = nameElement.textContent;
var alpha2Element = recordElement.getElementsByTagName("alpha-2")[0];
recordObj.alpha2 = alpha2Element.textContent;
var alpha3Element = recordElement.getElementsByTagName("alpha-3")[0];
recordObj.alpha3 = alpha3Element.textContent;
var capitalcityElement = recordElement.getElementsByTagName("capital-city")[0];
recordObj.capitalcity = capitalcityElement.textContent;
return recordObj;
}
function displayCountrylist(countrylistObj)
{
for(var i=0; i < countrylistObj.recordList.length; i++)
{
var recordObj = countrylistObj.recordList[i];
html += "country-code: " + recordObj.countrycode;
html += "<br />";
html += "name: " + recordObj.name;
html += "<br />";
html += "alpha-2: " + recordObj.alpha2;
html += "<br />";
html += "alpha-3: " + recordObj.alpha3;
html += "<br />";
html += "capital-city: " + recordObj.capitalcity;
html += "<br />";
}
var displayDiv = document.getElementById("display1");
displayDiv.innerHTML = html;
}
</script>
<body>
<button onClick="makeAjaxQueryCountrylist()"> Region Info I (Format: region-fmt-1.xsl)</button>
<br /><br />
<div id="display1">
</div>
</body>
</html>
There isn't any problem with my XML codes so it has to be some error from here.
You got that error html is not defined because you are using html variable without declaring it. So, before the line
html += "country-code: " + recordObj.countrycode;
you have to write
let html = '';

How to get this data using the loop?

How do i show all the data by using the loop to display all the data from json to html ?
ATM , I am able to print one of the data. but if i am using data[i] the code will not display any data.
I think I mess up the the concept of object and array.
please advice me , how to loop thru object , like array?
thanks
var getWeather = document.getElementById('weather');
var requestWeather = new XMLHttpRequest();
//+'-31' +'&lon='+'150'
requestWeather.open('GET','https://fcc-weather-api.glitch.me/api/current?lat=-31&lon=150');
requestWeather.onload = function () {
var weatherData = JSON.parse(requestWeather.responseText);
console.log(weatherData);
getHTML(weatherData);
};
requestWeather.send();
function getHTML(data) {
var weatherString = "";
for(var i in data.weather ){
var x= data.weather[i].main;
weatherString+= "<p class='weather'>" + x + "</p>";
// weatherString+= "<p>" + data.currently.summary + "</p>";
// console.log(data[i].city);
}
getWeather.insertAdjacentHTML("beforeend", weatherString);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weather"></div>
to get all data check for object and do recursive loop
var getWeather = document.getElementById('weather');
var requestWeather = new XMLHttpRequest();
//+'-31' +'&lon='+'150'
requestWeather.open('GET', 'https://fcc-weather-api.glitch.me/api/current?lat=-31&lon=150');
requestWeather.onload = function() {
var weatherData = JSON.parse(requestWeather.responseText);
//console.log(weatherData);
getHTML(weatherData);
};
requestWeather.send();
function getHTML(data) {
var weatherString = "";
for(var i in data) {
var x = data[i];
if(typeof(x) == "object") {
getHTML(x);
}
else {
weatherString += "<p class='weather'><b>" + i + "</b>: " + x + "</p>";
// weatherString+= "<p>" + data.currently.summary + "</p>";
// console.log(data[i].city);
}
}
getWeather.insertAdjacentHTML("beforeend", weatherString);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weather"></div>
var getWeather = document.getElementById('weather');
var requestWeather = new XMLHttpRequest();
//+'-31' +'&lon='+'150'
requestWeather.open('GET', 'https://fcc-weather-api.glitch.me/api/current?lat=-31&lon=150');
requestWeather.onload = function() {
var weatherData = JSON.parse(requestWeather.responseText);
getHTML(weatherData);
};
requestWeather.send();
function getHTML(data) {
var weatherString = "";
for (var i in data.weather) {
var x = data.weather[i].main;
weatherString += "<p class='weather'>" + x + "</p>";
$.each(data.main, function(i, f) {
var main = "<div>" + i + ": " + f + "</div>";
$(main).appendTo("#main");
});
}
getWeather.insertAdjacentHTML("beforeend", weatherString);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weather"></div>
<div id="main"></div>
use foreach loop to iterate over all object
read more from here

Getting results from logger to return to web app

I am very close, however not there yet. The logger displays the search results- however I still am not able to get the results to display on the web app.
The search on the web app does work and the results display in the logger.
Please advise. Thanks!
Here is updated,
Code:
function SearchFiles(searchTerm) {
var searchFor ="title contains '" + searchTerm + "'";
var owneris ="and 'Email#email.com' in Owners";
var names =[];
var fileIds=[];
Logger.log(searchFor + " " + owneris);
var files = DriveApp.searchFiles(searchFor + " " + owneris);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId();// To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i=0;i<names.length;i++){
//this is showing in the Logger
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
}
function returnNames() {
var names = SearchFiles();
return '<b>returnNames has ran.!</b> <br>' + names ;
}
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate()
.setTitle('Hello World')
// .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(searchTerm) {
var resultToReturn;
Logger.log('processForm was called! ' + searchTerm);
resultToReturn = SearchFiles(searchTerm);
Logger.log('resultToReturn: ' + resultToReturn)
// shows as undefined in the logger
return resultToReturn;
}
function helloWorld()
{
return "Hello World!";
}
INDEX:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function displayMessage() {
var searchTerm;
searchTerm = document.getElementById('idSrchTerm').value;
console.log('searchTerm: ' + searchTerm );
google.script.run.processForm(searchTerm);
google.script.run.withSuccessHandler(handleResults).returnNames();
}
function handleResults(returnVal){
console.log('Handle Results was called! ');
document.writeln(returnVal);
}
</script>
</head>
<body>
<input type="text" id="idSrchTerm" name="search">
<input type="button" value="submitButton" name="submitButton" onclick="displayMessage()"/>
</body>
</html>
You are missing the withSuccessHandler of the script runner.
Check out the docs at:
https://developers.google.com/apps-script/guides/html/reference/run#withSuccessHandler(Function)
example:
<script>
google.script.run
.withSuccessHandler(handleResults)
.processForm(searchTerm);
function handleResults(returnVal){
console.log(returnVal)
}
</script>

Why Uncaught TypeError: Cannot read property 'length' of undefined?

<html>
<head>
<meta charset="utf-8">
<script src="dist/localforage.js"></script>
<script type="text/javascript">
"use strict"
var value1;
var $id = function(id) { return document.getElementById(id); }
var certArr;
window.onload = function()
{
$id("read-button").addEventListener("change", onChangeFile, false);
};
function onChangeFile(e) {
alert("aaaaddffd");
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var Oribuf = e.target.result;
var certArr = new Uint8Array(Oribuf);
alert(certArr);
};
reader.readAsArrayBuffer(file);
alert("aaaa: " + certArr);
readFile(certArr);
};
function readFile(arrData) {
// Here. Why this alert Undefined?
alert("bbbbb: " +arrData);
var key = 'STORE_KEY';
var r = document.getElementById('results');
localforage.setItem('cert1', 1234688, function(err, value) {
r.innerHTML += 'Saved: ' + value + '<br />';
});
localforage.getItem('cert1', function(err, value) {
// console.log(value);
r.innerHTML += 'Read: ' + value + '<br />';
} );
localforage.keys(function(err, keys) {
r.innerHTML += 'keys: ' + keys + '<br /><br />';
});
// Here. Why Uncaught TypeError: Cannot read property 'length' of undefined?
// How can I solved this problem. Help me.
alert(arrData.length);
alert("aad: " + arrData);
var text = "";
for(var i=0;i<arrData.length;i++)
text += " " + arrData[i];
localforage.setItem(key, text, function(e) {
var tmp_func = function(err, readValue) { r.innerHTML += 'Read: ' + readValue + '< br />'; };
r.innerHTML += 'Saved: ' + text + '<br />';
});
alert("ccccc");
};
function selectCert(sel){
if(parent.middle.document.getElementById("test").innerHTML == "1")
parent.middle.document.getElementById("test").innerHTML = "2";
else
parent.middle.document.getElementById("test").innerHTML = "1";
parent.middle.reload();
}
</script>
</head>
<body>
<ul>
<div id="results"></div>
<input id="read-button" type="file" />
<li id="qwer" onclick="selectCert(1)">1</li>
<li id="asdf" onclick="selectCert(2)">2</li>
</ul>
</body>
</html>
This is my HTML 5 and JavaScript code. It uses local storage, file API, etc.
Why does this code show me the following error?
Uncaught Type Error: Cannot read property 'length' of undefined
Two words: variable scope.
You've defined certArr in the beginning of your file using
var certArr;
... but you effectively re-declare it within your function by using the var keyword again:
var certArr = new Uint8Array(Oribuf);
To access the globally-declared version of certArr, remove the var keyword:
certArr = new Uint8Array(Oribuf);
remove this variable
var certArr;
Add This type variable
var certArr = new Uint8Array();
beginning of the code

Categories