title: How to list contents of a directory IN ORDER with node.js?
body: <p>I'm a fairly experienced programmer and I've just recently discovered node.js. I love JavaScript because that's where I started (Web Development) so being able to write server-side code with its is amazing.</p>
  
  <p>Currently, I'm working on a simple exercise, a WebSocket/HTTP server, and I began to add a directory list function when I ran into a slight annoyance: when I list directories and files in a certain directory they're not in any order. I would like them to be listed with directories first, files second than alphabetically (like the 'ls' command). I have a feeling its because its asynchronus but I'm not totally positive. Any help would be appreciated.</p>
  
  <p>BTW, here's my code:</p>
  
  <pre><code>var sys = require("sys");
  var ws = require('websocket-server');
  var fs = require("fs");
  var path = require("path");
  var url = require("url");
  
  function log(data){
    sys.log("\033[0;32m"+data+"\033[0m");
  }
  
  var server = ws.createServer();
  server.listen(3400);
  log("Listening on 3400 for HTTP and WS");
  
  server.addListener("request", function(request, response){
    log("HTTP: Connected: " + request.connection.remoteAddress);
    var uri = url.parse(request.url).pathname;
    var filename = path.join("/home/brandon", uri);
    log("HTTP: " + request.connection.remoteAddress + " Requested: " + filename);
    path.exists(filename, function(exists) {
          if(!exists) {
              response.writeHead(404, {"Content-Type": "text/plain"});
              response.write("404 Not Found\n");
              log("HTTP: " + filename + " Does Not Exist. 404 returned to " + request.connection.remoteAddress);
              response.end();
              log("HTTP: Disconnected: " + request.connection.remoteAddress);
              return;
          }
  
          fs.readFile(filename, "binary", function(err, file) {
              if(err) {
                  if(err.errno === 21){
                      fs.readdir(filename, function(err1, files){
                          if(err1){ 
                              response.writeHead(500, {"Content-Type": "text/plain"});
                              response.write("Error when reading directory: " + err1 + "\n");
                              log("HTTP: " + filename + " Could Not Be Read. 500 returned to " + request.connection.remoteAddress);
                              response.end();
                              log("HTTP: Disconnected: " + request.connection.remoteAddress);
                              return;
                          } else {
                              response.writeHead(200);
                              response.write("&lt;HTML&gt;&lt;HEAD&gt;&lt;title&gt;Directory Listing for " + uri + "&lt;/title&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;h1&gt;Directory Listing for " + uri + "&lt;/h1&gt;");
                              response.write("&lt;ul&gt;");
                              function printBr(element, index, array) {
                                  response.write("&lt;li&gt;" + element + "&lt;/li&gt;");
                              }
                              /*for( i in files ){
                                  response.write("&lt;li&gt;" + files[i] + "&lt;/li&gt;");
                              }*/
                              files.forEach(printBr);
                              response.write("&lt;/ul&gt;");
                              response.write("&lt;/BODY&gt;&lt;/HTML&gt;");
                              log("HTTP: Directory listing for " + filename + " sent to " + request.connection.remoteAddress);
                              response.end();
                              log("HTTP: Disconnected: " + request.connection.remoteAddress);
                              return;
                          }
                      });
                      return;
                  }
                  response.writeHead(500, {"Content-Type": "text/plain"});
                  response.write("Error when reading file: " + err + "\n");
                  log("HTTP: " + filename + " Could Not Be Read. 500 returned to " + request.connection.remoteAddress);
                  response.end();
                  log("HTTP: Disconnected: " + request.connection.remoteAddress);
                  return;
              }
  
              response.writeHead(200);
              response.write(file, "binary");
              log("HTTP: " + filename + " Read and Sent to " + request.connection.remoteAddress);
              response.end();
              log("HTTP: Disconnected: " + request.connection.remoteAddress);
          });
      });
  });
  
  server.addListener("connection", function(conn){
    log(conn.id + ": new connection");
    server.broadcast("New Connection: "+conn.id);
    conn.addListener("readyStateChange", function(readyState){
      log("stateChanged: "+readyState);
    });
  
    conn.addListener("close", function(){
      var c = this;
      log(c.id + ": Connection Closed");
      server.broadcast("Connection Closed: "+c.id);
    });
  
    conn.addListener("message", function(message){
      log(conn.id + ": "+JSON.stringify(message));
  
      server.broadcast(conn.id + ": "+message);
    });
  });
  </code></pre>
  
  <p>And here's the output in the browser:
  <img src="https://i.stack.imgur.com/a8WJM.png" alt="Output in Browser"></p>
  
  <h1>**SOLVED:**</h1>
  
  <p>Thanks to @Samir, I found out how to do exactly what I wanted to do. I iterated through the array of the directory contents, checked if an item was a directory or file, separated them into two arrays ('dirs_in' for dirs and 'files_in' for files), sorted the two arrays alphabetically, and finally wrote them out.</p>
  
  <p>Code (Lines 42-70):</p>
  
  <pre><code>response.writeHead(200);
  response.write("&lt;HTML&gt;&lt;HEAD&gt;&lt;title&gt;Directory Listing for " + uri + "&lt;/title&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;h1&gt;Directory Listing for " + uri + "&lt;/h1&gt;");
  response.write("&lt;ul&gt;");
  function printBr(element, index, array) {
      response.write("&lt;li&gt;" + element);
      if( fs.statSync( path.join(filename + element) ).isDirectory() ){
          response.write(" is a &lt;b&gt;dir&lt;/b&gt;");
      } else {
          response.write(" is a &lt;b&gt;file&lt;/b&gt;");
      }
      response.write("&lt;/li&gt;");
  }
  var dirs_in = [];
  var files_in = [];
  function sep(element, index, array) {
      if( fs.statSync( path.join(filename + element) ).isDirectory() ){
          dirs_in.push(element);
      } else {
          files_in.push(element);
      }
  }
  files.forEach(sep);
  dirs_in.sort().forEach(printBr);
  files_in.sort().forEach(printBr);
  response.write("&lt;/ul&gt;");
  response.write("&lt;/BODY&gt;&lt;/HTML&gt;");
  log("HTTP: Directory listing for " + filename + " sent to " + request.connection.remoteAddress);
  response.end();
  log("HTTP: Disconnected: " + request.connection.remoteAddress);
  </code></pre>
  
  <p>Browser Output:
  <img src="https://i.stack.imgur.com/qrKKl.png" alt="Problem Solved">
  P.S. I'll remove the 'is a dir' and 'is a file'. They were just for testing.</p>