Cannot call recursion function in javascript / Polymer

I have a function that searches the folder tree and finds the parent folder of the selected folder.

Here is the function.

getParentFolder: function (searchroot, childFolder) { searchroot.subfolders.forEach(function (folder) { if (folder.key == childFolder.key) { return searchroot; } else { if (folder.subfolders) { return this.getParentFolder(folder, childFolder); } } }); } 

When I call it using this.getParentFolder(rootFolder, childFolder);

It just gives me: Uncaught TypeError: this.getParentFolder is not a function Why is this? In the same file, I call other functions that they work perfectly. This is the only function I cannot call with. Is it due to recursion?

+5
source share
2 answers

You must store this in a variable as you change your context inside the forEach method.

 getParentFolder: function(searchroot, childFolder) { var self = this; searchroot.subfolders.forEach(function(folder) { if (folder.key == childFolder.key) { return searchroot; } else { if (folder.subfolders) { return self.getParentFolder(folder, childFolder); } } }); } 

In addition, the return will not work the way you want. I recommend you list the array using a for loop:

 getParentFolder: function(searchroot, childFolder) { for (var i = 0; i < searchroot.subfolders.length; i++) { var folder = searchroot.subfolders[i]; if (folder.key == childFolder.key) { return searchroot; } else { if (folder.subfolders) { return self.getParentFolder(folder, childFolder); } } } } 
+5
source

The problem is that your this is different from the function you passed to forEach . You need to bind the external this to the internal function:

 getParentFolder: function(searchroot, childFolder) { searchroot.subfolders.forEach(function(folder) { if (folder.key == childFolder.key) { return searchroot; } else { if (folder.subfolders) { return this.getParentFolder(folder, childFolder); } } }, this); // pass in outer this as context for inner function } 

From Array.prototype.forEach() to MDN:

Syntax:

 arr.forEach(function callback(currentValue, index, array) { //your iterator }[, thisArg]); 

Alternative solution using ES6:

Like mishu mentioned in the comments, the new ES6 arrow syntax also solves this problem. Your code in ES6 will look something like this:

 getParentFolder: function(searchroot, childFolder) { searchroot.subfolders.forEach((folder) => { if (folder.key == childFolder.key) { return searchroot; } else { if (folder.subfolders) { return this.getParentFolder(folder, childFolder); } } }); } 

The ES6 arrow functions do not bind this (see MDN ), so the external this can be obtained from inside the arrow function.

Please note that not all browsers support arrow functions (see Browser Compatibility in MDN ). To support older browsers, you can redirect ES6 to ES5 using Babel .

+3
source

Source: https://habr.com/ru/post/1270925/


All Articles