By Taira


2017-02-15 21:35:27 8 Comments

I'm currently in the process practicing using electron, but I'm quite new with javascript and I've come across a problem which has me completely baffled. I have the following code:

    function getPaths() {
      var dirPath = document.getElementById("mdir").innerHTML;
      var filePaths = [];
      fs.readdir(dirPath, function(err, dir) {
        for(var i = 0, l = dir.length; i < l; i++) {
          var filePath = dir[i];
          filePaths.push(dirPath + "/" + filePath);
        }
      });
      console.log(filePaths);
      console.log(filePaths.length);
    }

Which is supposed to look into a directory defined by dirPath, then it loops through and obtains the full path of all files in that directory. It appends them to an array, and then at the bottom, it logs the array to the console, followed by the length of the array. What is baffling me is that given that code, the array logs to the console like expected, but then the console logs zero as the length. My current thinking is that it's got something to do with scope, but that doesn't make sense because I'm declaring the array, filePaths in the function above the one that's running. Unless I've missed something. Could anyone point out what I'm doing wrong?

2 comments

@ibrahim mahrir 2017-02-15 21:39:38

readdir is asynchronous. It won't get the result right away. You should log the filePaths inside the callback. The only reason why the console show the value is because the console evaluate the array when you unfold it.

When you press the little arrow on the left, put the mouse on the i box on the right. What happen is that the console keeps a reference to the array, so when the user unfold the array it then show what its current value is. But when you log filePaths.length the array is empty because readdir didn't finish reading yet that's why you get 0. But by the time you open the console and press that arrow, readdir will already be done reading and the console will print the current value of the array (after it been filled).

enter image description here

Example to demonstrate the problem: (not a solution, it's just to understand what is really happening)

Try and run this code and see what happen:

var arr = [];
setTimeout(function() {
  arr.push(1, 2, 3);
}, 5000);
console.log(arr.length);
console.log(arr);

Here the array and it's length are both logged before the array is filled. The array will be filled after 5 seconds. So the output will be 0 and a string array[]. Now because arrays could have tons of data, the console won't show that data untill the user unfold the array. So what the console does is keep a reference to the array untill the user press unfold arrow. If you unfold the array before 5 seconds you see that the array is empty (not filled yet). If you wait untill the 5 seconds pass then unfold it, then you'll see that it's filled.

Note: Also, the line that get logged to the console (something like > Array(0)) is just a string representation of the object/array at the moment the log happens. It won't get updated if the object/array changes. So that also may seem confusing sometimes.

I hope it's clear now.

@MaxZoom 2017-02-15 22:51:51

I would not recommend to use setTimeout function as the response time could vary significantly based on the directory content

@ibrahim mahrir 2017-02-15 22:54:08

@MaxZoom I didn't suggest setTimeout as a solution! I just explained the OP's problem using a easy-to-understand example using setTimeout to emphasize on the asynchronousity of the problem!

@Taira 2017-02-15 23:12:11

Ok, so if I've got this right, the reason why I'm not getting a value is because readdir is asynchronous. As a result, console.log() completes before the array has been built, and as a result it returns 0?

@ibrahim mahrir 2017-02-15 23:15:54

@Taira exactly! readdir will just regester the callback to be called when the reading is done, and proceed to the next statement and execute it (pretty much the same of what happening with setTimeout))! If you want the synchronous version use readdirSync (but I wouldn't recommend it).

@Taira 2017-02-15 23:18:39

Ok, that makes sense! I come from a background in Python, so this type of thing is quite foreign to me. One other question though: out of curiosity, why would readdirSync not be recommended?

@ibrahim mahrir 2017-02-15 23:25:16

@Taira the best about NodeJS (the thing that electron uses) is the asynchronousity of its I/O methods. Why? Because I/O method could be slow sometimes, so it's not good to block everything waiting for the function to complete. The best approach is to regester a callback for the function to call once it's done reading. Imagine if the reading took 1 to 2 seconds (just imagine), then nothing else will be executed during that time. But if it's asynchronous, you could do a lot of stuff during that time. See the diference?

@Taira 2017-02-16 00:54:27

Yes, I do. Thank you!

@Jeremy Jackson 2017-02-15 21:41:17

Just to expand on @ibrahim-mahrir 's answer, they means like this

function getPaths() {
    var dirPath = document.getElementById("mdir").innerHTML;
    var filePaths = [];
    fs.readdir(dirPath, function(err, dir) {
        for (var i = 0, l = dir.length; i < l; i++) {
            var filePath = dir[i];
            filePaths.push(dirPath + "/" + filePath);
        }
        console.log(filePaths);
        console.log(filePaths.length);
    });
}

Related Questions

Sponsored Content

89 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6166750 View
  • 7691 Score
  • 89 Answer
  • Tags:   javascript arrays

41 Answered Questions

[SOLVED] Loop through an array in JavaScript

56 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

34 Answered Questions

[SOLVED] Create ArrayList from array

37 Answered Questions

[SOLVED] Deleting an element from an array in PHP

  • 2008-12-15 20:28:55
  • Ben
  • 2460982 View
  • 2373 Score
  • 37 Answer
  • Tags:   php arrays unset

47 Answered Questions

[SOLVED] How to check if an object is an array?

47 Answered Questions

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

16 Answered Questions

[SOLVED] How to insert an item into an array at a specific index (JavaScript)?

30 Answered Questions

[SOLVED] How to append something to an array?

Sponsored Content