Let's say I have a script that runs a for loop that outputs x number of new script lines depending on what a user answers. This script's main purpose is to construct an outgoing SOAP message with defined parameters. The for loop creates additional parameters to add to the existing parameters that are hardcoded into the script. How do I add these new parameters from the for loop to the script? Basically, add lines of script within the script (print to the script)... I can include the script if need be.
Thanks!
You can use arrays with array.push(element) to make this happen. Arrays are incredibly powerful for processing like what you're describing, and we use them in our app for this purpose.
var scripts = [];
for(var i=0; i < data; i++) {
scripts.push(data[i]);
}
Then if you need a single string at the end you can use join like this scripts.join(). Note that you could also add line returns if you want too.
However, it sounds like you do want to process the results of the scripts in order, at which time you can just loop through that array and send the parameters to another function one at a time.
There are a lot of functions in the array object that will help with what you're trying to do. Here is a link to the MDN docs for your reference.
Related
Disclaimer: I just started with JavaScripts/GoogleForms
I want to validate some data with a GoogleForm that I've created. Each section contains 5 multiple choice questions. In the example below I've shown how I add one question to the section.
// Sentence 1
sentence = form.addMultipleChoiceItem();
choices = [
sentence.createChoice('Answer I'),
sentence.createChoice('Answer II'),
sentence.createChoice('Answer III'),
]
sentence.setTitle(pred_1) // pred_1 -> Variable extracted from the dataset
.setChoices(choices);
In the end, I can build an excellent-looking form that contains 20 sections with five questions each based one a single dataset in my Google Drive Folder.
However, I want to extend this. I have ten different datasets that I want to have evaluated. A straightforward approach is copying the script ten times and pointing the script towards a different dataset. However, with this approach, I have to run the script ten times, and every time I adjust something (e.g. in the Title/HelpText), I have to rerun all the scripts.
I was thinking there should be a solution where I just read all the file inside my Drive folder and run my main scripts that produces the forms for multiple dataset. I was thinking something like this:
function createForms() {
// Folder with data
var folder = DriveApp.getFolderById('FOLDERID')
// List files
var files = folder.getFiles()
for (var i = 1; i < 11; i++) {
createMultipleChoiceForm(files[i]) // Function that creates a single form
}
}
This does unfortunately does not work at all (it does not give any errors, but does not produce anything).
EDIT:
This does actually work, but it creates a new form every time without saving it (it overruns the previous version).
I final approach is of course concatenating all the 10 datasets, and sample them from within the Google Script editor. But I still want to end up with ten different form (so I can send them to different people.
I hope anyone can give me some pointers in the right direction.
Thanks!
The Folder.getFiles() method returns a FileIterator object rather than an array. The code in the question ends up calling createMultipleChoiceForm() with an undefined parameter every time.
To make it work, replace the for loop with this pattern:
const files = folder.getFiles();
while (files.hasNext()) {
createMultipleChoiceForm(files.next());
}
I want to search a sheet for a value in a sheet, and then return the row and the column where the value was found.
I am well-versed in VBA and have used the .Find function to accomplish this very easily. However, after searching for the last 30 minutes online, I have been stunned to discover that is is so hard to find the code for this extremely simple function. I feel like I am in the twilight zone. Does Javascript really not have anything analogous to .Find? If so, why is this language used so much when VBA appears to be able to accomplish the same tasks in a much more simple manner? Please advise.
I assume you are calling something like mysheet.getDataRange().getValues(), which returns the contents of a google sheet as an array of arrays, eg, [[row1A, row1B], [row2A, row2B]].
With JS, you can get the index of a value in an array using indexOf, which returns the index of the found item or -1 if the item is not in the array. I don't think you can directly search across the two nested arrays. Instead, you could try iterating over the outer array and searching the inner array. Something like this:
// get data from google sheet, doing something like this
var data = mysheet.getDataRange().getValues()
// define our own function
function findItem(data) {
// loop over outer array
for (var i=0; i < data.length; i++) {
var row = data[i]; // get the inner array
var idx = row.indexOf(searchValue); // search for value
// if the value is found, return [row, column]
if (idx > -1) {
return [i, idx];
}
}
// call the function
var res = findItem(data);
var row = res[0];
var col = res[1];
You're comparing apples and oranges. JavaScript and VBA are different languages with different goals. VBA was built to allow it to integrate seamlessly with the MSSQLServer. JavaScript in its native form has no relational-database functionality at all. It's meant more for manipulating web pages through the DOM. (It can do more than that, but that's its primary function.) While VBA can do some of the things Javascript can do, it's a rather clunky way (IMHO) of doing so and narrowly focused on a rather specific set of problems that are tied to very specific software and hardware infrastructures. While that functionality might be nice to have in some cases, most of the JavaScript you see on the web today isn't interested in databases at all.
It's not clear to me what source of data you're trying to connect to but if you are specifically looking for a JavaScript data solution you might want to look into something like MongoDB, and the code libraries that have been developed specifically for that. And there are tons of other JS libraries that are relational-data or database-specific, and you can search places like npm for those. Or you can combine JavaScript with languages that inherently include database functionality, and PHP is an excellent example of that.
I have inherited some code that uses the Play! framework which has scala.html files that have javascript in them. Play! and scala are all new to me.
One of the javascript functions does a post and gets back a JSON object. It then loops through the JSON object and creates an array.
var myArray = [];
function createArray(){
$.post('/createArray', $('#arrayForm').serialize()).done(function( data ) {
var obj1 = JSON.parse(data);
$.each(obj1, function(idx, obj) {
myArray.push(obj.name);
});
});
return true;
}
It then uses this array (of strings) to create a text input field that does autocomplete using the data in the array.
I want/need to convert this text input to a select dropdown using the Play! #select but the options arg for #select wants a List object (or Map or Seq - just figured List would be easier since I already have an array of strings).
If I manually create the List object, it works fine.
#select(pForm("equipName"), options(scala.collection.immutable.List("Yes","No")))
The problem is I cannot figure out how to convert the myArray array to a List object which I can then pass to the #select options.
I have found a lot of posts that talk about converting a scala List to an array but can't find a way to go the other way. I am hoping it is an easy thing that I can't seem to figure out.
Thanks in advance for the help.
You can not do that. And more precisely - you do not want to do that.
So basically your play application run on server. In your Play application all those .scala html files are compiled to generate some functions.
Now, when a play application receives a request from a client browser, it gets mapped to some controller by by router. The controller does some processing and finally take one of these above functions ( lets say for index.scala.html we get views.html.index ) and call this function with some parameters.
These functions returns some text which is then sent to the client's browser as HTTP response with response header Content-Type:text/html; charset=utf-8 which tells the browser to treat this text as html.
Now, the browser renders the html which has embedded JavaScript and hence runs the JavaScript. So... basically your JavaScrpt code does not exist on server... for play all of it is just text.
Both of these Scala code and JavaScript code are executed at very different times, at different computers and in different environments hence you can not do whatever you are saying.
I'm sitting here for a while now wondering why I'm losing an array parameter on a function call when calling it a second time.
The script I'm working on is mapped after CouchDB/PouchDB and stores items as JSON strings in multiple storages (including local storage). Parameters are:
_id id of the item
_rev revision string (version), counter and hash
_content whatever content
_revisions array of all prior hashes and current counter
_revs_info all previous revisions of this item with status
I'm currently trying a PUT operation which by default updates an existing document. As I'm working with multiple storages, I also have a PUT SYNC, which "copy&pastes" versions of a document from one storage to another (with the goal having every version available on every storage). I'm also keeping a separate file with a document tree, which stores all the version hashes. This tree file is updated on SYNCs using the _revs_info supplied with the PUT.
My problem is sequential SYNC PUTs. The first one works, on the second I'm losing the _revs_info parameter. And I don't know why...
Here is my first call (from my QUnit module), which works fine:
o.jio.put({
"content":'a_new_version',
"_id":'myDoc',
"_rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89",
"_revs_info":[
{"rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89","status":"available"},
{"rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123","status":"deleted"},
{"rev":fake_rev_1,"status":"deleted"},
{"rev":fake_rev_0,"status":"deleted"}
],
"_revisions":{
"start":4,
"ids":[
"b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89",
"a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123",
fake_id_1,
fake_id_0
]}
},
function(err, response) {
// run tests
});
However, when I call the same function a second time:
o.jio.put({
"content":'a_deleted_version',
"_id":'myDoc',
"_rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61",
"_revs_info":[ {"rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61","status":"deleted"},{"rev":"2-67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844","status":"deleted"},{"rev":fake_rev_2,"status":"deleted"}],
"_revisions":{
"start":3,
"ids":[
"05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61",
"67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844",
fake_id_2
]}
},
function(err, response) {
// run tests
});
My script fails, because the _revs_info array does not include anything. All other parameters and all random parameters I'm adding are transferred. If I add a string or object instead of an array they also safely make it into my script alive.
Array however... does not pass...
Question:
I have been sitting on this for a few hours trying to nail down points I have not found, but I'm pretty clueless. So does anyone know of reasons, why arrays might lose their content, when passing them on as parameters in Javascript?
Thanks!
EDIT:
I added a regular PUT after my first SYNC-PUT, which passed fine (without _revs_info being defined).
It's completely possible for a JavaScript function to mutate an array passed in. Consider this example:
function removeAll(a) { a.splice(0); }
var arr = [1, 2, 3];
removeAll(arr);
console.log(arr); // empty array
I have a component which writes/generates javascript from a server side renderer. This component can be used in multiple times in a same page. However, once the page is loaded I have to collect all the variables or JSO written by this multiple components in the page. How can I do this so that I will have a collection of all the variables or JSO?
For e.g. If this component (lets say ) is used twice in the page then it emits two javascript block on client/browser -
var arr1 = new Array['First', 'Second'] and
var arr2 = new Array['Third', 'Fourth'].
In order to make a final rendering I have to combine these two arrays.
You will need to be a little more specific about your problem, maybe with an example page but here are some thoughts.
If you have a server-side component that writes JavaScript during page generation, I would generate a function call each time, something like:
Component_appendArray(['First', 'Second']);
...
Component_appendArray(['Third', 'Fourth']);
then ensure that you have your function Component_appendArray() defined before these calls:
var globalArray = [];
function Component_appendArray(array)
{
globalArray = globalArray.concat(array);
}
At the end, globalArray should contain:
['First', 'Second', 'Third', 'Fourth']
Hope this helps.
Although I do not understand the entire scenario, let me suggest that if you are printing out variables throughout the HTML in order to use them after the page loads, that you instead use hidden input fields. I see this often, where variables are used to pass values to a function or a script at the bottom of the page, but using the values of hidden input fields allows you to get all your scripts out of the content areas. It makes for a cleaner solution.