I am new to the world of * AppScript * I am currently designing a ** WepApp ** which is made up of html lists that connect to Mysql, when I individually test my lists paint correctly and their icons modify and update the data, without However ** the problem is ** when I join all my lists and call them through their corresponding url only the last one paints me the others are blank. For example of 10 lists I call # 2 the log tells me to call 10; I call 5 the same thing happens and if I call 10 it paints the data and they are allowed to be modified.
Within what I have searched I find that my problem lies in the way I render my pages but I cannot find the right path, so I ask for your support.
function doGet(e) {
var template ;
var view = e.parameters.v;
if(view == null){
template = HtmlService.createTemplateFromFile("Index");
}if(view == "Index"){
template = HtmlService.createTemplateFromFile("Index");
}if(view != null && view != "Index"){
template = HtmlService.createTemplateFromFile(view);
}
return template.evaluate()
.setTitle('Documental')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function getTemplate(view){
return HtmlService.createTemplateFromFile(view);
}
and with this JavaScript method I connect my appscript code to pass it to my html
window.onload = function () {
google.script.run
.withSuccessHandler(run_This_On_Success)
.withFailureHandler(onFailure)
.readAreaPRE();
};
function onFailure(error) {
var div = document.getElementById("output");
div.innerHTML = "ERROR: " + error.message;
}
function run_This_On_Success (readAreaPRE) {
let table = $("#selectTable");
table.find("tbody tr").remove();
table.append("<tr><td>" + "</td><td>" + "</td></tr>");
readAreaPRE.forEach(function (e1, readAreaPRE) {
table.append(
"<tr><td>" +
e1[0] +
"</td><td>" +
e1[1] +
"</td><td>" +
"<p><a class='modal-trigger' id=" + e1[0] + " href='#modal1' onclick='capturaid("+e1[0]+",'"+ e1[1]+"')'><i class='material-icons'>edit</i></a>" +
"<a class='modal-trigger' href='#modal3' onclick='capturaidsup("+e1[0]+")'><i class='material-icons'>delete</i></a></p>" +
"</td></tr>"
);
});
};
function capturaidsup(dato1){
$("#delAreaPRE").val(dato1)
}
function capturaid(item1,item2) {
$("#uptAreaPRE1").val(item1);
$("#uptAreaPRE2").val(item2);
}
here is my function: readArePRE
function readAreaPRE() {
var conn = Jdbc.getCloudSqlConnection(url, user, contra);
var stmt = conn.createStatement();
stmt.setMaxRows(1000);
var results = stmt.executeQuery(
"CALL `BD_CENDOC_COL`.`sp_lee_tb_ref_AreasPRE`()"
);
var numCols = results.getMetaData().getColumnCount();
var rowString = new Array(results.length);
var i = 0;
while (results.next()) {
var id_areaPRE = results.getInt("id_areaPRE");
var AreaPRE = results.getString("AreaPRE");
rowString[i] = new Array(numCols);
rowString[i][0] = id_areaPRE;
rowString[i][1] = AreaPRE;
i++;
}
return rowString;
conn.close();
results.close();
}
Thank you in advance, any correction to ask my question will be welcome.
I am pulling data from my remote database and get this JSON data:
{"list1":{"id":1, "item":"testobj1"},"list2":{"id":2, "item":"testobj2"},"list3":{"id":3,
"item":"testobj3"},"list4":{"id":4, "item":"testobj4"},"list5":{"id":5, "item":"testobj5"}}
I can now loop through the objects in the data and display a list of objects on my screen. It works fine:
var d = JSON.parse(hr.responseText);
databox.innerHTML = "";
for (var o in d) {
if (d[o].item) {
databox.innerHTML += '<p>' + d[o].item + '</p>' + '<hr>';
}
}
Now however, I would like to insert this data into my Sqlite database. I am not quite sure how I can tell the loop that 'd[o].id' and 'd[o].item' are the items I would like insert into my db.
db.transaction(function(tx) {
var sql = "INSERT OR REPLACE INTO testTable (id, item) " + "VALUES
(?, ?)";
log('Inserting or Updating in local database:');
var d = JSON.parse(hr.responseText);
var id = d[o].id;
var item = d[o].item;
for (var i = 0; i < d.length; i++) {
log(d[o].id + ' ' + d[o].item);
var params = [d[o].id, d[o].item];
tx.executeSql(sql, params);
}
log('Synchronization complete (' + d + ' items synchronized)');
}, this.txErrorHandler, function(tx) {
callback();
});
I hope somebody can take a look at this loop and tell me where did I go wrong. Many thanks in advance!
You're iterating over d as if it's an array rather than an object. Something like this is probably what you're looking for:
var d = JSON.parse(hr.responseText);
for (var o in d) {
var params = [d[o].id, d[o].item];
tx.executeSql(sql, params);
}
I have a problem when trying to store the results of a select query into an array with java script .
the problem is that inside the function the array is containing the right values but outside it's empty , even when i used a global var it's still empty !!!
db.transaction(function (transaction) {
var sql = "SELECT * FROM Question where idEnq=" + idEn;
transaction.executeSql(sql, undefined, function (transaction, result) {
var res = document.getElementById('results');
res.innerHTML = "<ul>";
if (result.rows.length) {
for (var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
ch[i] = new qu(row.id, row.text, row.type);
res.innerHTML += '<li>' + row.id + ' ' + ch[i].text + ' ' + ch[i].type + '</li>';
}
tablo = ch;
} else {
alert("No choices");
res.innerHTML += "<li> No choices </li>";
}
res.innerHTML += "</ul>";
}, onError);
}); // here the ch and the tablo array are empty
You are using asynchronous functions. Anything that wants to use the data "returned" by those functions need to be in the callback. Of course you can assign this data e.g. to a global variable, but that variable will only have the value after the callback has run (asynchronously).
you're new so have look here http://pietschsoft.com/post/2008/02/JavaScript-Function-Tips-and-Tricks.aspx
there's a part talking about calling JavaScript Function asynchronously
I am trying to write a Javascript function that obtains an array of unique ids from an sqlite database & then passes them to be used in another function where the ids can be used in another sql query, they also form part of a dynamically created list.
I have managed to pass the ids row['id'] to the array variable window.symp[i]. But I have not been able to access them correctly in the second function below, the second function correctly uses the ids to create the dynamic html but the variable passed to the sqlite query either fails or is the same value in all the list items created. Any help would be greatly appreciated - I have included both functions below:
function showContent() {
db.transaction(function (tx) {
tx.executeSql("SELECT id, notes FROM webkit WHERE notes LIKE 'A%'", [], function (tx, result) {
var notesanode = document.getElementById('notesa');
notesanode.innerHTML = "";
for (var i = 0; i < result.rows.length; ++i) {
var row = result.rows.item(i);
window.symp[i] = i;
window.symp[i] = row['id'];
var noteadiv = document.createElement('div');
noteadiv.innerHTML = '<li class=\"arrow\"><a id=\"0\" onClick=\"showSymptoms()\" href=\"#symptoms\">' + row['notes'] + " " + row['id'] + '</a></li>';
notesanode.appendChild(noteadiv);
}
}, function (tx, error) {
alert('Failed to retrieve notes from database - ' + error.message);
return;
});
});
}
function showSymptoms() {
db.transaction(function (tx) {
tx.executeSql("SELECT sid, symptom FROM slinks WHERE id LIKE ('" + symp + "')", [], function (tx, result) {
var symptomnode = document.getElementById('symptomid');
symptomnode.innerHTML = "";
for (var i = 0; i < result.rows.length; ++i) {
var row = result.rows.item(i);
var symptomdiv = document.createElement('div');
symptomdiv.innerHTML = '<p><label> <input type=checkbox>' + row['symptom'] + '</label></p>';
symptomnode.appendChild(symptomdiv);
}
}, function (tx, error) {
alert('Failed to retrieve notes from database - ' + error.message);
return;
});
});
}
I see two things:
The main issue is that you need
"SELECT sid, symptom FROM slinks WHERE id LIKE ('" + window.symp.join(',') + "')"
instead of what you have up there.
The second issue is that you have
window.symp[i] = i;
window.symp[i] = row['id'];
you can just go ahead and remove window.symp[i] = i; because it gets immediately overwritten by the line that follows it.
I've got the following JSON structure that defines a table and it's data.
var arrTable =
[{"table": "tblConfig",
"def":
[{"column": "Property", "type": "TEXT NOT NULL"},
{"column": "Value", "type": "TEXT NOT NULL"}],
"data":
[{"Property": "VersionNumber", "Value": "1.0"},
{"Property": "ReleaseDate", "Value": "2010-01-01"}]
}]
The code describes a table named "tblConfig" with two columns, "Property" and "Value" both are type "TEXT NOT NULL". The table has two rows of data.
Property_______Value_____
VersionNumber 1.0
ReleaseDate 2010-01-01
Below is my Javascript code to create and populate the table. It builds the create table SQL great but I'm having trouble with the populate function.
dbController.updateDatabase = function () {
this.db.transaction(function (transaction) {
//load data.json
var dbDefs = dbController.jsonObject(url + "data.json")
//parse array "table"
eval(dbDefs);
for (var i in arrTables) {
createTable(arrTables[i].table, arrTables[i].def, arrTables[i].data);
}
//create table
function createTable(table, arrDef, arrData) {
var arrColumns = [];
var strSQL = "CREATE TABLE " + table + " (";
for (var j in arrDef) {
arrColumns.push(arrDef[j].column);
strSQL += arrDef[j].column + " " + arrDef[j].type + ", ";
}
strSQL = strSQL.substring(0, strSQL.lastIndexOf(",")) + ")";
transaction.executeSql(strSQL, [],
function () {
console.log(table + " created.");
populateTable(table, arrData);
return;
},
dbController.errorHandler
);
}
//populate table
function populateTable(table, arrData) {
...
}
});
};
I want to be able to get the column names ("Property" & "Value") out of the "data" object and use them in the insert SQL string. I thought something like this would work.
//populate table
function populateTable(table, arrColumns, arrData) {
var strVal;
var arrVal;
for (var k in arrData) {
strVal = "?,";
arrVal.push(arrData[k]. ~~ KEY VALUE NAME ~~ )
}
var strSQL = "INSERT INTO " + table + " (" + strCol + ") ";
strSQL += "VALUES (" + strVal.lastIndexOf(",") + ");";
transaction.executeSql(strSQL, arrVal, null, dbController.errorHandler);
console.log(" " + table + " populated.");
}
The bugger is the bolded statement. I've tried using .hasOwnProperty() on arrData but that only returns 0 and 1, not the words "Property" and "Value". I don't want to use the "arrData[k].Property" notation because there are many more tables in the schema and I don't want to write create and insert statements for each table.
Any help is greatly appreciated.
Thanks to everyone for their help and head-scratching due to my late-night post. My intention with this function was to have a JSON object that defined multiple tables and held the table's data. Since none of the tables have the same number of columns or column names I had to devise a way of getting the data out of "data" without using the object.member syntax. I had forgotten about the object["member"] syntax.
Here's the solution.
dbController.updateDatabase = function (a) {
this.db.transaction(function (transaction) {
//load data.json
var dbDefs = dbController.jsonObject(dbController.dbFolder + "data.json")
//parse array "table"
eval(dbDefs);
for(var i in arrTables) {
createTable(arrTables[i].table, arrTables[i].def, arrTables[i].data);
}
//create table
function createTable(table, arrDef, arrData){
var arrColumns = [];
var strSQL = "Create Table " + table + " (";
for(var j in arrDef) {
arrColumns.push(arrDef[j].column);
strSQL += arrDef[j].column + " " + arrDef[j].type + ", ";
}
strSQL = strSQL.substring(0, strSQL.lastIndexOf(",")) + ")";
transaction.executeSql(strSQL, [],
function() {
console.log(table + " created.");
populateTable(table, arrColumns, arrData);
return;
},
dbController.errorHandler
);
}
//populate table
function populateTable(table, arrColumns, arrData) {
for (var k in arrData) {
var arrVal = [];
var strVal = "";
for (var l = 0; l < arrColumns.length; l++) {
strVal += "?,";
arrVal.push(arrData[k][arrColumns[l]])
}
var strSQL = "Insert Into "+table+" (" + arrColumns.toString()+") ";
strSQL += "Values ("+strVal.substring(0, strVal.lastIndexOf(","))+");";
transaction.executeSql(strSQL, arrVal, null, dbController.errorHandler);
}
console.log(" " + table + " populated.");
}
});
};
I'm making some assumptions here, but try changing:
for (var k in arrData) {
strVal = "?,";
arrVal.push(arrData[k]. ~~ KEY VALUE NAME ~~ )
}
var strSQL = "INSERT INTO " + table + " (" + strCol + ") ";
strSQL += "VALUES (" + strVal.lastIndexOf(",") + ");";
to:
for (var i =0; i < arrColumns.length; ++i) strVal += ',?';
for (var k in arrData)
{
arrVal[k] = [];
for (var i in arrColumns)
arrVal[k].push (arrData[k][arrColumns[i]]);
}
var strSQL = "INSERT INTO " + table + " (" + strCol + ") ";
strSQL += "VALUES (" + strVal.substr(1) + ");";
If I'm correct in thinking that transaction.executeSql(strSQL, arrVal, null, dbController.errorHandler); accepts multiple records, then this should work fine. Otherwise, call
transaction.executeSql(strSQL, arrVal[0], null, dbController.errorHandler);
instead
Don't you just want to look at the first row of your 'data' element and enumerate through those keys (assuming all the rows are the same)?
for (var k in arrData[0]) {...
In Javascript, and time you have an object with members that you can access via obj.member, you can also access it as obj["member"]. Objects in JavaScript are essentially just hash tables with the ability to call methods on them (which are also just entries in the hash table), and a prototype based inheritance system.
Anyhow, that means that you can use for ... in to iterate over the properties in that hash table, and pull out the keys.
So, if I understand what you're trying to do correctly, you could just do something like this (note that the structure of this loop is somewhat different than the one in your question, as you're going to need one INSERT statement for each row to insert, while your loop had the construction of the INSERT statement outside of the loop over the data rows):
function populateTable(table, data) {
for (var k in data) {
var queryArgs = [];
var argArray = [];
var columns = [];
for (var col in data[k]) {
queryArgs.push('?');
columns.push(col);
argArray.push(data[k][col]);
}
var SQL = "INSERT INTO " + table + " (" + columns + ") VALUES " +
"(" + queryArgs + ");";
alert(SQL + " [" + argArray + "]")
}
}