I am trying to have apps script set a value in a table and then on success go to the BOMOnSuccess
function where it will reload the values of the modified table.
The problem I am having is it seems like the code continues on before the value is actually set, so the table is retrieved is not up to date and what is being shown in my HTML page is not accurate.
When I "refresh" the HTML page it is correct again. What I need to happen is upon entering the new value in the prompt, for the cell value to be set and that new value is reflected in the listbox.
I have tried all sorts of different pauses both in .gs (Utilities.sleep
) and javascript. None of which seem to make a difference.
Some of the times it would actually pause the server from setting the value even if I have is sleep after the line that sets it. Other times if I get it to pause correctly it still has the old data.
I also tried SpreadsheetApp.flush
after setValue
, however it made no difference.
.gs:
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
function showForm() {
var html = HtmlService.createTemplateFromFile('Form')
.evaluate();
html
.setTitle('AP Pricing Form')
.setWidth(600)
.setHeight(500);
var dialog = ui.showModalDialog(html, "AP Pricing App")
}
function getBom(){
var sheet = ss.getSheets()[4]
var vals = sheet.getDataRange().getValues();
return vals
}
function updateMaterialQuantity(qty,prod,mat){
var sheet = ss.getSheets()[4]
var values = sheet.getDataRange().getValues();
for(var i = 1; i<values.length; i++){
if(values[i][0] == prod){
if(values[i][1] == mat){
sheet.getRange(i+1,3).setValue(qty);
SpreadsheetApp.flush();
return;
}
}
}
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
};
js:
//get BOM from BOM table
function refreshBOM(prodOption){
for (a in document.getElementById("productMaterials").options) { document.getElementById("productMaterials").options.remove(a); }
prod = prodOption
function filterBOM(array){
var newBom = [];
for(var i = 1; i<array.length; i++){
if(array[i][0] == prod){
newBom.push(array[i])
}
}
return newBom;
}
function BOMOnSuccess(array){
bom = array
bom = filterBOM(bom);
for(var i = 0; i < bom.length; i ++){
var opt = document.createElement("option");
opt.text = bom[i][2] + " - " + String(bom[i][1]);
opt.text = opt.text.toUpperCase();
opt.value = bom[i][1];
document.getElementById("productMaterials").options.add(opt);
}
}
google.script.run.withSuccessHandler(BOMOnSuccess).getBom();
}
//edit materials
function editProductQty(material){
if(material != ""){
var qty = prompt("Enter new quantity");
var prod = document.getElementById("productsSelect").value
google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);
}
else{
alert("Please choose a product and material");
}
}
What is expected, is for editProductQty
to run when a button is clicked. That will cause the user to enter the new value. Then updateMaterialQuantity
will run.
This will go to .gs and the range will be found and the new value set. Then refreshBOM
is run where it will get the newly updated range and the new value will be shown on the HTML page.
What is actually happening is when getBOM
is called, it somehow is getting the old non-updated version of the table. I believe the problem is that the actual setting of the value is happening after the js code finishes for some reason but I am not sure.