0

I'm having problems when i try to call a instance method recursively.

The code looks as follows:

import fs from 'fs';
import fsWatcher from 'filewatcher';
import path  from 'path';

export default class SearchService {
initializeFileWatcher(foldersToWatch) {
    let result = fsWatcher();
    for (var i = 0; i < foldersToWatch.length; i++) {
        result.add(foldersToWatch[i]);
    }
    return result;
}

  getFilesFromDirectoriesRecursively(directories, fileExtension) {
    let result = [];

    for (var i = 0; i < directories.length; i++) {
        var dir = directories[i];
        var list = fs.readdirSync(dir);
        list.forEach(function (file) {
            file = dir + '/' + file;
            var stat = fs.statSync(file);
            if (stat && stat.isDirectory())
                result = result.concat(this.getFilesFromDirectoriesRecursively([file], fileExtension).bind(this));
            else
            if (path.extname(file) === fileExtension)
                result.push(file);
        });
    }
    return result;
}

getFilesFromDirectory(directory, fileExtension) {
    var result = [];
    var files = fs.readdirSync(directory);
    for (var i = 0; i < files.length; i++) {
       if (files[i].endsWith(fileExtension))
           result.push(files[i]);
    }
    return result;
}

}

The code get transpiled with babel-es2015 and runs on a electron app environment. No when I try to call the method getFilesFromDirectoriesRecursively inside itself the transpiled code get in troubles because of the this which point to the instance in es2015 but not in the transpiled code.

How can I get around this problem?

Oliver
  • 367
  • 5
  • 17
  • 2
    It's not transpilation issue - `this` does not refer to what you think it does there, since you use it within an anonymous function. Read through http://stackoverflow.com/q/3127429/251311 – zerkms Oct 14 '16 at 22:41
  • `How can I get around this problem?`. By changing `list.forEach(function (file) {` to `list.forEach(file => {`. – noppa Oct 14 '16 at 23:12

1 Answers1

0

I could solve the problem. As @zerkms mentioned is was using the this keyword false. I tried to bind this with the .bind keyword what does not work with anonymous functions.

So I applied the the solution described here: How to pass context to forEach() anonymous function

list.forEach( (file) => {
            file = dir + '/' + file;
            let stat = fs.statSync(file);
            if (stat && stat.isDirectory())
                result = result.concat(this.getFilesFromDirectoriesRecursively([file], fileExtension));
            else
            if (path.extname(file) === fileExtension)
                result.push(file);
        }, this);

Now its passing the this to the closure on the forEach function call

Edit:

It's not necessary to pass this because the arrow function is doing this.

list.forEach( (file) => {
        file = dir + '/' + file;
        let stat = fs.statSync(file);
        if (stat && stat.isDirectory())
            result = result.concat(this.getFilesFromDirectoriesRecursively([file], fileExtension));
        else
        if (path.extname(file) === fileExtension)
            result.push(file);
});
Community
  • 1
  • 1
Oliver
  • 367
  • 5
  • 17
  • passing the context here is unnecessary - just the change to ES6 arrow syntax should be sufficient to fix the problem – Alnitak Oct 15 '16 at 13:18