aeruhxi
aeruhxi

Reputation: 556

Weird behavior in array

In NodeJS, I was trying to read files in a directory and its subdirectories recursively

export const readDirRecursively = (rootDir) => {
  const files = [];

  return new Promise((resolve, reject) => {
    // Inner function for recursive operation
    function innerFun(dir) {
      fs.readdir(dir, (err, xpaths) => {
        if (err) reject(err);

        for (let xpath of xpaths) {
          const absPath = path.join(dir, xpath);
          if (fs.statSync(absPath).isDirectory()) {
            innerFun(absPath);
          } else {
            files.push(absPath);
          }
        }
      });
    }

    innerFun(rootDir);  // Call innerFun to initate
    console.log(files);   // contains vaules as expected
    console.log([...files]);  // empty array
    console.log(files.map(file => file + ' test')); // empty array

    const testVar = [1,2,3,4];
    console.log([...testVar]);    // This log [1,2,3,4] as expected

    resolve(files);
  });

};

And I found this unusual behavior with the array. Array files contains items as expected after recursive function is called. But when I try to map or copy with rest/spread operator or iterate over it, that array turns out empty.

I tried the same with [1,2,3,4] just to make sure. With it, everything works as expected. However, only files array shows this unusual behavior.

Upvotes: 2

Views: 120

Answers (1)

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324640

When you log the array, are you then expanding it out in the console afterwards?

You've logged an array. Not a value, but an object. So when you go to view it, it shows you the values at the time you view it. But when you do [...files], that's a new array constructed from the values of the old one (which there aren't any of yet) and this new array isn't modified by the asynchronous function so you just see that empty array.

Same for files.map(...) because that also returns a new array with no values.

And finally testVar doesn't change between the time you log it and the time you view the expanded object in your console.

When debugging objects, consider using console.log(JSON.stringify(files)) to get a "snapshot" of it.

Upvotes: 2

Related Questions