Recursive function doesn't return all data - javascript

I want to list only the folder names from a specific drive in Drive. So I first call the function getFolderNames() and add the parent folder name there. Then I call the getChildFolders(parent) function which gets all the sub-folders and keeps getting called recursively for every sub folder.
My problem is that the variable folderatt (which is supposed to hold all the information about the folder names) has only the names of the first folder, so only the sub-folders of the parent folder. But when I log inside the recursive function, it displays all the folder and sub-folder names correctly.
function getFolderNames() {
var folderatt = [];
try {
// If you want a tree of any sub folder
var parent = DriveApp.getFoldersByName("Librari").next();
var dhenat = getChildFolders(parent);
folderatt.push(dhenat);
} catch (e) {
Logger.log(e.toString());
}
return folderatt;
}
function getChildFolders(parent) {
folderNames = [];
var childFolders = parent.getFolders();
var thirr = 1;
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
var allFolders = {};
allFolders.emri = childFolder.getName();
allFolders.id = childFolder.getId();
folderNames.push(allFolders);
thirr++;
folderNames.push(thirr);
// Logger.log(childFolder.getName());
// Logger.log(folderNames);
// Recursive call for any sub-folders
getChildFolders(childFolder);
}
return folderNames;
}

JSFiddle - Have a look at this fiddle.
Declare and initialize your 'folderNames' variable outside the recursive function. That should solve your problem. Also, you need not to return it to 'dhenat' variable in your parent fucntion as now 'folderNames' will hold the results

There are a couple of problems I can see with your code, but first and for most would be that you don't really do anything with the result of the getChildFolders( childFolder ) call, so naturally, it doesn't get included in the result set, now possibly you could change it to this
// Recursive call for any sub-folders
folderNames.concat( getChildFolders( childFolder ) );
But you should be aware, that currently your folderNames variable is a global variable (as it is not really defined, you just assign it a value). As long as it is global, even the concat won't help you, so you also have to assign it, eg:
let folderNames = [];
The reason that it won't help would be that each time you call the getChildFolders function, the folderNames would be set to an empty array again in your example, so folderNames would only contain the results of the last time you called getChildFolders( childFolder ). By defining it locally, there won't be such a side effect
So in the end, the first function can be rewritten as:
function getChildFolders(parent) {
let folderNames = [];
let childFolders = parent.getFolders();
while (childFolders.hasNext()) {
let childFolder = childFolders.next();
let allFolders = {
emri: childFolder.getName(),
id: childFolder.getId()
};
folderNames.push(allFolders);
// Recursive call for any sub-folders
folderNames.concat( getChildFolders( childFolder ) );
}
return folderNames;
}
Please note that I removed the thirrr variable, as it was unclear to me for what purpose you need it.
In the end this should give you a flattened array that contains your allFolders object. I also changed the var to let keywords as var is a function scoped keyword, that doesn't make sense to be defined inside a block (in this case, your while loop)

Related

how to access global variable from function in javascript

I am trying to access global variable from function, i want to call variable outside from inside function variable.This is what I tried.
Note: the query function should be work after click on query function from html drop down selection.
Thank you for helping.
HTML
<select name="myInput" id="choice1">
<li><option value="6011">apib_cadastral:bivel</option></li>
<li><option value="6012">apib_cadastral:burhchaura</option></li>
</select>
javascript
var layer_name;
function query() {
var text_value = document.getElementsByName('myInput')[0];
var layer_name = text_value.options[text_value.selectedIndex].text;
}
query();
var config = {
geojson: layer_name,
};
Remove the "var" inside the function. With that you define a new variable that exists inside the function.
You should change your code in this way.
Because, when you re-declare variable inside query() it will occupy another cell from memory with different address. And, variable inside config object cannot access it. It will access layer_name [first defined] which contains undefined value
var layer_name ;
function query() {
var text_value = document.getElementsByName('myInput')[0]
layer_name = text_value.options[text_value.selectedIndex].text;
}
query();
var config = {
geojson: layer_name
}
In addition to other answers, which correctly state that you should remove var from the variable declaration inside the query() function, you could change the function to return the value, rather than relying on shared/global state.
function query() {
var text_value = document.getElementsByName('myInput')[0];
return text_value.options[text_value.selectedIndex].text;
}
var config = {
geojson: query()
};
Note that this may have a performance impact depending on how many times you call query() as the return value would have to be computed each time, but it's worth considering from the perspective of alleviating the need for shared/global state.
Also note, consider replacing var with more modern const and let...
const when the variable is initialised and never needs to change.
let when the variable needs to change beyond initialisation.
function query() {
const text_value = document.getElementsByName('myInput')[0];
return text_value.options[text_value.selectedIndex].text;
}
const config = {
geojson: query()
};

Table data is not appending when in a function

Whenever I write my code iteratively the program runs as it is supposed to, but when I place in a function like this it breaks.
function create_tableElements() {
Let myArticle = document.createElement(‘tr’);
Let rank = document.createElement(‘td’);
}
function assign_tableElements() {
Let count = 1
rank1 = count;
rank.textContent = rank1;
heroes_name.textContent = heroes[i].name;
}
function append_tableElements() {
myArticle.appendChild(rank);
myArticle.appendChild(heroes_name);
}
Does anyone know why this may happen? Is there a way for me to call a function within a function? I am using a for loop to loop through JSON. Now if I do not place in a function and just write the code, it will run perfectly fine. Just working on readability, and organizing my code better
There's a couple issues with the code you pasted (Let instead of let or the fancy single quotes).
I'm going to assume your phone or whatever tool you used corrected it. So let's say this is your code :
function create_tableElements() {
let myArticle = document.createElement('tr');
let rank = document.createElement('td');
}
function assign_tableElements() {
let count = 1;
rank1 = count;
rank.textContent = rank1;
heroes_name.textContent = heroes[i].name;
}
function append_tableElements() {
myArticle.appendChild(rank);
myArticle.appendChild(heroes_name);
}
Your code can't work because :
the rank variable is local to the create_tableElements function and can't be accessed by the append_tableElements function
same goes for the heroes_name function, it's local to the assign_tableElements function
You can fix this by :
either declaring these variables as global variables, outside of any function. It's not really a best practice, though.
change your function's definition so that they can access the same local variables : do you really need a function to create elements and another to append them to the DOM?
you could also use an Immediately Invoked Function Expression.
(function() {
// these variables will be visible to all the functions defined in this function, but won't be global :
let rank, myArticle, heroes_name;
function create_tableElements() {
myArticle = document.createElement('tr');
rank = document.createElement('td');
}
function assign_tableElements() {
let count = 1;
rank1 = count;
rank.textContent = rank1;
heroes_name.textContent = heroes[i].name;
}
function append_tableElements() {
myArticle.appendChild(rank);
myArticle.appendChild(heroes_name);
}
// invoking your functions :
create_tableElements();
assign_tableElements();
append_tableElements();
})();

Updating an array returned by a function

I've been trying to implement some card game using Javascript. In the snippet below, I simply want to pull two cards from the top of the deck and give it to the player (simplified logic below)
function deck() {
var faceCards = [['jack', 11],['queen', 12],['king', 13]];
return faceCards;
}
function removeCard() {
var singleCard = deck().pop();
var faceValue = singleCard[0];
return faceValue;
}
var cardPair = [removeCard(),removeCard()];
console.log(cardPair);
However the faceCards array is still the same even after popping off its cards which means that the next card will be the same as well as seen in cardPair array.
I need to mirror the effects I used inside of the
removeCard() function to reflect back in the deck() function.
I suppose I could either create the faceCards array in the global scope or use 'this' in some way (which I don't really want as I'm not much familiar with it). How can I update one function from inside another function? Thank you very much for reading this.
Your error is here:
var singleCard = deck().pop()
The call to deck() creates a new array of cards every time it's called, and doesn't repeatedly return the same array.
If you don't want to go full OO yet, consider at least passing the deck as a parameter to the removeCard() function, i.e.
function removeCard(deck) {
var singleCard = deck.pop();
var faceValue = singleCard[0];
return faceValue;
}
var deck = newDeck();
var pair = [ removeCard(deck), removeCard(deck) ];
but ultimately you should longer term be going for a full OO solution, where your usage might then become:
var deck = new Deck();
var pair = [ deck.takeCard(), deck.takeCard() ];
implementation of this is out of scope of this particular question.
You're creating a new array every time you run deck(). Try saving the deck in an array and running pop on this:
function deck() {
var faceCards = [['jack', 11],['queen', 12],['king', 13]];
return faceCards;
}
function removeCard(fromDeck) {
var singleCard = fromDeck.pop();
var faceValue = singleCard[0];
return faceValue;
}
var thisDeck = deck();
var cardPair = [removeCard(thisDeck),removeCard(thisDeck)];
console.log(cardPair);

Create variable to JavaScript array from another function?

I have a function that create and store an array for all the p elements:
function dummyArray(){
var $dummy= $('p');
var dummy= [];
i = 0;
$dummy.each(function()
{
dummy[i++] =$(this).html();
});
return dummy;
}
Now, in order to reuse the array in another function, I can use dummyArray() and dummyArray()[0] to access the individual data.
function initAll(){
//dummyArray();
//dummyArray()[0];
}
However I want to store it inside a variable like below but it gives me error.
function initAll(){
var allArray = dummyArray();//error
}
Is there a way to store it inside a variable or is there a better way of doing this?
After cleaning up my code I noticed that using var allArray = dummyArray(); does work, the error was generated from something else. cheers~
Edited:
The error I found out was the function name cannot be the same as the new variable name declared even though the () aren't there.
var dummyArray = dummyArray();//error
var allArray = dummyArray();//works

jquery ajax callback function without dynamic parameters

I have an array with objects, I want to save each one of them via GET, and update certain params in the callback, bot
the html:
<html><body><div id='test'><div id="a">a</div><div id="b">b</div></div></body></html>
the js:
$.map($("#test > div"), save)
save = function(o,i){
itt = $(o)
tmp = {'desc':itt.html()};
$.get('ajax/update_post', {'data':array2json(tmp)}, function(a){
alert(itt.attr('id'))
updatePostBack(a,itt)
})
}
updatePostBack = function(a,item){
alert(item.attr('id'))
}
the updatePostBack is always receiving the las item!
how can I pass the right id or object to a callback function in js / jquery?
The solution is so sadly mundane: you needed to add var in front of your variables to declare them as new. They were being overwritten inappropriately by the next iteration before the first one could complete. This code works for me:
save = function(o,i){
var itt = $(o)
var tmp = {'desc':itt.html()};
$.get('ajax/update_post', {'data':array2json(tmp)}, function(a){
alert(itt.attr('id'))
updatePostBack(a,itt)
})
}
updatePostBack = function(a,item){
alert(item.attr('id'))
}
$.map($("#test > div"), save);
I also moved the map statement to the end so that it's calling the save function after it's been declared.

Categories

Resources