I'm going crazy for the strange behaviour of the Iterators in Google Apps Script.
My script picks a random folder (corresponding to a year between 2012 and the current year), then pick a random image in. The file's random criterion is a led by a random integer which stops the loop at the integer-th iteration.
It works, the debug and the script silently execute. But, but, but: the photo-rolling rendering of the script deliveries always the same 4-5 pictures. They are thousands.
I control the caching, also the F12 function tabs says the cache is null and Ctrl+F5 does not any positive effect.
Then, I ask the script to log the URL of the image. Surprise: even if the random number that enters the if-statement is different, however the resulting URL is the same. By chance, the folder is the same, but the different random numbers get the same image picked.
HELP!
function doGet() {
var folderImmagini_ID ="myID";
//---
// picking year folder between 2012 and current year
var annoCorrente = new Date().getFullYear();
var numFolderRandom = Math.random() * (annoCorrente - 2011) + 1;
var nomeFolderRandom = (numFolderRandom + 2011).toString();
var nomeFolderFinale = nomeFolderRandom.substring(0, nomeFolderRandom.indexOf("."));
// once get random folder, picking a random image
var foldersIterator = DriveApp.getFolderById(folderImmagini_ID).getFolders();
var nomeCartella, cartella;
while (foldersIterator.hasNext()) {
cartella = foldersIterator.next(),
nomeCartella = cartella.getName();
if (nomeCartella == nomeFolderFinale) {
var filesIterator = cartella.getFiles();
var numeroFiles = 0, file;
while (filesIterator.hasNext()) {
numeroFiles = numeroFiles + 1;
file = filesIterator.next();
}
var numFileRandom = Math.floor(Math.random() * numeroFiles) + 1;
var ordineFile = 0;
filesIterator = cartella.getFiles();
while (filesIterator.hasNext()) {
ordineFile = ordineFile + 1;
if (ordineFile == numFileRandom) {
var t = HtmlService.createTemplateFromFile('OutputHTML');
var foto = filesIterator.next();
t.fotoID = foto.getId();
Logger.log("nome folder: %s, numero random: %s, link foto: %s",nomeCartella, numFileRandom,
"https://drive.google.com/uc?export=download&id="+ t.fotoID);
return t.evaluate();
}
}
}
}
};
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
</head>
<body>
<center><img src="https://drive.google.com/uc?export=download&id=<?= fotoID ?>" height="85%" width="85%"></center>
</body>
</html>
When I saw your showing script, it seems that var foto = filesIterator.next();
is used in the if-statement of if (ordineFile == numFileRandom) {,,,}
. In this case, when ordineFile == numFileRandom
is true, var foto = filesIterator.next();
is used for the first time. In this case, I'm worried that ordineFile = ordineFile + 1;
is not used for selecting the file. I thought that this might be the reason for your current issue.
If you want to modify your showing script, how about the following modification?
while (filesIterator.hasNext()) {
ordineFile = ordineFile + 1;
if (ordineFile == numFileRandom) {
var t = HtmlService.createTemplateFromFile('OutputHTML');
var foto = filesIterator.next(); // <--- here
t.fotoID = foto.getId();
Logger.log("nome folder: %s, numero random: %s, link foto: %s", nomeCartella, numFileRandom,
"https://drive.google.com/uc?export=download&id=" + t.fotoID);
return t.evaluate();
}
}
while (filesIterator.hasNext()) {
ordineFile = ordineFile + 1;
var foto = filesIterator.next(); // <--- here
if (ordineFile == numFileRandom) {
var t = HtmlService.createTemplateFromFile('OutputHTML');
t.fotoID = foto.getId();
Logger.log("nome folder: %s, numero random: %s, link foto: %s", nomeCartella, numFileRandom,
"https://drive.google.com/uc?export=download&id=" + t.fotoID);
return t.evaluate();
}
}
var foto = filesIterator.next();
was moved outside of the if-statement of if (ordineFile == numFileRandom) {,,,}
.As another approach, I thought that the file is randomly selected from the file ID list. In this case, how about the following modification?
function doGet() {
var folderImmagini_ID = "myID";
//---
// picking year folder between 2012 and current year
var annoCorrente = new Date().getFullYear();
var numFolderRandom = Math.random() * (annoCorrente - 2011) + 1;
var nomeFolderRandom = (numFolderRandom + 2011).toString();
var nomeFolderFinale = nomeFolderRandom.substring(0, nomeFolderRandom.indexOf("."));
// once get random folder, picking a random image
var foldersIterator = DriveApp.getFolderById(folderImmagini_ID).getFolders();
var nomeCartella, cartella;
// I modified the below script.
while (foldersIterator.hasNext()) {
cartella = foldersIterator.next(), nomeCartella = cartella.getName();
if (nomeCartella == nomeFolderFinale) {
var filesIterator = cartella.getFiles();
var fileIds = [];
while (filesIterator.hasNext()) {
fileIds.push(filesIterator.next().getId());
}
var numFileRandom = Math.floor(Math.random() * fileIds.length);
var t = HtmlService.createTemplateFromFile('OutputHTML');
t.fotoID = fileIds[numFileRandom];
Logger.log("nome folder: %s, numero random: %s, link foto: %s", nomeCartella, numFileRandom + 1, "https://drive.google.com/uc?export=download&id=" + t.fotoID);
return t.evaluate();
}
}
}