How to change a range on the go - javascript

function copyM1toM2() {
const activeRange1 = ss.getSheetByName("OA M1").getRange("A1:F8");
ss.getSheetByName("OA M2").getRange("F8").activate();
activeRange1.copyTo(ss.getActiveRange(),SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
What do I do to change the getRange("A1:F8") values on the go. Like getRange("A+var1:F+var2"), where var1 and var2 are defined elsewhere thru some other function. I am a newbie. Thanks.
I have tried many permutations but have failed. Am unable to use query function, which works on the sheet but not in script.

Related

How to make consecutive API calls in JavaScript with variables [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 9 months ago.
Sorry if this is kind of a "noob" question but I'll ask anyway. :)
I have a HTML page and a JavaScript file where I make two API calls to get train trip information.
You are filling out the city you want to travel from and the first API call returns an ID for that location.
The the second API call is supposed to use this received ID to get you up to six upcoming departures from that location to a preset destination.
The first API call works with the variable cityname being passed from the input field from the HTML page and in the log I get an ID number back. That is shown in the console logs. Unfortunately I'm not allowed to provide a picture (too low reputation :)).
The second API call always fails since the variable trainoriginid always ends up empty (I guess that this is actually a variable scope issue). I have tried to use the same technique on the second API call as in the first call, as you can see in the commented "var url" line, but no matter where I try to declare or set the trainoriginid it ends up empty. How am I to pass the result from the first API call to the second? All info is appreciated.
This line is from the error message:
GEThttps://api.resrobot.se/v2.1/trip?format=json&originId=&destId=740098037&passlist=true&showPassingPoints=true&accessId
If I use the call with the "const url" line everything works so there you can see what the url should look like.
The (not complete) JavaScript code looks like this:
let reqBtn = document.querySelector('.request-btn');
let reqInput = document.querySelector('.request-input');
let respResultDiv = document.querySelector('.response-result');
let trainoriginid = '';
reqBtn.addEventListener('click', event => {
let cityName = reqInput.value;
console.log(cityName);
var citylookup = `https://api.resrobot.se/v2.1/location.name?input=${cityName}&format=json&accessId=[APIKey]`;
axios.get(citylookup).then(searchresponse => {
console.log(searchresponse.data);
let searchdata = searchresponse.data;
trainoriginid = searchdata.stopLocationOrCoordLocation[0].StopLocation.extId;
console.log(trainoriginid);
});
//var url = `https://api.resrobot.se/v2.1/trip?format=json&originId=${trainoriginid}&destId=740098037&passlist=true&showPassingPoints=true&accessId=[APIKey]`;
const url = `https://api.resrobot.se/v2.1/trip?format=json&originId=740000008&destId=740098037&passlist=true&showPassingPoints=true&accessId=[APIKey]`
axios.get(url).then(response => {
console.log(response.data.Trip);
let data = response.data.Trip;
NOTE!
After following the link above and and doing some testing - using callbacks solved my problem. Just for reference the final solution looks like this:
reqBtn.addEventListener('click', event => {
let cityName = reqInput.value;
respResultDiv.textContent = '';
console.log(cityName);
getStationId(cityName, getTrainList)
});
function getStationId(cityNameinput, callback){
var citylookup = `https://api.resrobot.se/v2.1/location.name?input=${cityNameinput}&format=json&accessId=[API-key]`;
var originid;
axios.get(citylookup).then(searchresponse => {
console.log(searchresponse.data);
let searchdata = searchresponse.data;
originid = searchdata.stopLocationOrCoordLocation[0].StopLocation.extId;
console.log(originid);
callback(originid);
});
}
function getTrainList(trainoriginid){
console.log(trainoriginid);
var url = `https://api.resrobot.se/v2.1/trip?format=json&originId=${trainoriginid}&destId=740098037&passlist=true&showPassingPoints=true&accessId=[API-key]`;
axios.get(url).then(response => {
console.log(response.data.Trip);
let data = response.data.Trip;
[Do a bunch of stuff with the result here]
});
}
In your example above, your second lookup call needs to be inside the "then" response method of the first lookup. You are calling both inline at the same time, so the second call will always use the empty "trainoriginid" as it is not set yet. Also, in your example above, I can not see you actually applying "${trainoriginid}" to the second url.
In this case, you do not need to make the second url a "const" as it is a one use deal. It is probably best to use "let" (and apply the "${trainoriginid}").
As a side note, axios is awaitable, so you could use await on the first call (and make the click method async), then you could have both lookups inline like that, but it is probably easier to just move the second call inside the the response of the first.

Onedit setvalues does not copy code values, only user input is copied

https://docs.google.com/spreadsheets/d/1rGns0DGQbjlEpxTbdy1T_-m2oh7eK8tM9xyDzGqahJo/edit?usp=sharing
So I have this code that I thankfully got of the internet but I can't seem to get it to copy the other values in column 'C' from a code I have that fills in empty cells, sheet provided for reference.
function ss1OnEdit(e){
if(e.range.getSheet().getName()!='source_sheet') return;
SpreadsheetApp.openById("1rGns0DGQbjlEpxTbdy1T_-m2oh7eK8tM9xyDzGqahJo").getSheetByName("target_sheet").getRange(e.range.getA1Notation()).setValue(e.value);
}
//You can run this function all you want it will not create more than one trigger. But you must run it once to setup the first trigger.
function createSS1OnEditTrigger() {
var ss=SpreadsheetApp.getActive();
var trgs=ScriptApp.getProjectTriggers();
var found=false;
for(var i=0;i<trgs.length;i++) {
if(trgs[i].getHandlerFunction()=="ss1OnEdit") {
return;
}
}
if(!found) {
ScriptApp.newTrigger("ss1OnEdit").forSpreadsheet(ss.getId()).onEdit().create();
}
}
This code only sets the values that have been entered manually by hand. I would really appreciate if we can have it set cell value from code input.
I have been reading about this for a bit and the getdisplayvalue() but nothing so far worked for me.
Thank you!
I assume that your question is why the user input fires the trigger, but the Range.setValues() doesn't. If that is correct, then it works as written on the simple trigger docs: «onEdit(e) runs when a user changes a value in a spreadsheet». So a user change will fire the trigger, but a script change won't.

JQuery - using previously declared variables for a click function

Have searched high an low for an answer without luck.
I am trying to pass a variable between two functions. The first function runs when the page loads, pulling settings from a google script file. I don't have any issues with this part. I am however, struggling with the second function which runs 'on click' and requires some variables from the first function.
Any guidance is appreciated.
<script>
$(function() {
google.script.run
.withSuccessHandler(loadSettings)
.withFailureHandler(showStatus)
.withUserObject($('#button-bar').get())
.getSettings();
function loadSettings(settings) {
$("select").data("option",settings.userInput1);
};
$('#add1').click(function(){
var option0 = $("select").data("option");}
...etc.
})
</script>
I assume settings.userInput1 is a string. Try the below
<script>
var userInput ="";
$(function() {
google.script.run
.withSuccessHandler(loadSettings)
.withFailureHandler(showStatus)
.withUserObject($('#button-bar').get())
.getSettings();
function loadSettings(settings) {
userInput = settings.userInput1;
$("select").data("option",settings.userInput1);
};
$('#add1').click(function(){
//you can now use userInput in this function
var option0 = $("select").data("option");}
...etc.
})
if other solutions are not working then you should go this way -
Make a hidden field
store that variables value in that hidden field
in the next function get the value from that field
$("#hiddenfield_id").val();

Set note from custom function

I'm struggling with following issue:
I have a spreadsheet responsible for tracking my stock market investments. It calls external service to get a CSV with current prices.
So, there is a function customFunction() that calls UrlFetchApp and returns current price of an item. I'd like it to add a note to the cell that it has been called from, containing current datetime. Something like this:
function customFunction() {
//get price from csv
var url = "http://sth.com";
var csv = UrlFetchApp.fetch(url);
var result = Utilities.parseCsv(csv);
var currentValue = parseFloat(result[1][6]);
//set note
SpreadsheetApp.getActiveSheet().getActiveCell().setNote("Hey, I'm the note with the datetime");
//return value so it can be set as cell value
return currentValue;
}
I am calling this function from cell E21 (value =customFunction()).
And so everything works as planned, except the line that supposed to set a note. I am sure I get correct cell (tested by returning A1notation as a value). I get the error:
error: You do not have permission to call setNote
Does anybody know if it's possible to set a note to the cell that calls a custom function from that function? Or maybe you have any idea of workaround, like catching the moment that function reloades with new data and using it as a trigger?
your problem is due to permission limitations:https://developers.google.com/apps-script/execution_custom_functions#permissions
the function SpreadsheetApp.getActiveSheet().getActiveCell() is not anonymous and can't be used here.
Unfortunately I don't know any efficient workaround

Variable not updating in script string, yet it updates

Very confused here.
I have a search box which reads a list of school names from my database. When I select a school, the id (from the db) gets put in a hidden textbox.
I also have a search box which reads a list of courses from my database. However, I made the query so that it only reads the courses from the selected school.
It does that, in theory.
I was planning to pass the school id, which I grab from the hidden box, to the search script which in turn passes it to my database query. However, the variable I put my school id in doesn't seem to be updating.. yet it does. Let me explain.
I come on the page. The school for my test account has id 1. The id number in my hidden box is indeed 1. I search for a school which I know has some courses assigned to it: the id number in the box changes to 3.
I have a JS variable called school_id which I declared outside of my $(document).ready. I assume that means it's global (that's what I got taught even though SO told me once it isn't really the correct way to do this. Still have to look into that). I wrote a function which updates this variable when the school search box loses focus:
$("#school").blur(function() {
school_id = $("#school_id").val();
});
A quick javascript:alert(school_id); in my browser bar also shows the updated variable: it is now 3 instead of 1.
Onto the search script part of my page (excerpt of the script):
script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&"
As you can see, I pass the school_id variable to the script here. However, what seems to be happening is that it always passes '1', the default variable when the page loads. It simply ignores the updated variable. Does this string get parsed when the page loads? In other words, as soon as the page loads, does it actually say &id=1? That's the only idea I can come up with why it would always pass '1'.
Is there a way to make this variable update in my script string? Or what would be the best way to solve this? I'm probably missing out on something very simple here again, as usual. Thanks a lot.
EDIT
Updated per request. I added a function getTheString as was suggest and I use the value of this function to get the URL. Still doesn't work though, it still seems to be concatenating before I get a chance to update the var. HOWEVER, with this code, my ajax log says id:[object HTMLInputElement], instead of id:1. Not sure what that means.
<script type="text/javascript">
var school_id;
$(document).ready(function() {
$("#school").blur(function() {
school_id = $("#school_id").val();
});
// zoekfunctie
var scholen = {
script:"/profiel/search_school?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:6,
callback: function (obj) { document.getElementById('school_id').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('school', scholen);
var richtingen = {
script: getTheString(),
varname:"input",
json:true,
shownoresults:true,
maxresults:6
};
var as_json2 = new bsn.AutoSuggest('studierichting', richtingen);
});
function getTheString() {
return "/profiel/search_richting?json=true&limit=6&id=" + school_id + "&";
}
</script>
This is because the URL is static, it is not updated as the ID changes.
You should update the URL as part of the code you wrote to get the ID:
$("#school").blur(function() {
school_id = $("#school_id").val();
// update URL here ...
});
Aren't you concatenating script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&" before the event is fired and the var updated?
Okay. So the problem was my third party plug-in instead of the code I wrote. I fixed this by editing the code of the autoSuggest plugin so it now includes my id field in the AJAX request.
var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp)+"&id="+ $("#school_id").val();
Thanks to everyone who tried to help me out!

Categories