Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to continue receiving asynchronous console.log messages in repl/bash w/ Node.js Commander?

I've got a Node.js CLI I've been building using the Commander Library. Here's the code from the main execution file.

#!/usr/bin/env node

var program = require('commander');
var scmStash = require('./lib/hdqc/scmStash');

var command = {};

program
    .version('0.0.1')
    .option('-P, --Projects', 'List Projects')
    .option('-R, --Repositories', 'List All Repositories on Server.')
    .parse(process.argv);

function listProjects() {
    scmStash.getProjectListing(function (data) {
        for (var i = 0; i < data.size; i++) {
            var project = data.values[i];
            console.log('    ' + i + ' ' + project.name + ' @ ' + project.link.url);
        }
    })
}

if (program.Projects) {
    console.log('  - Projects');
    listProjects();
}

I've been building this in WebStorm, and when I call the command using the node.js running everything works perfectly. for example, if I run the WebStorm runner executing the ./strack -P command to output the project, the output looks like this...

node strack -P
  - Projects
    0 Business Insights @ /projects/BI
    1 Platform @ /projects/HDP
    2 H @ /projects/H
    3 QC Application Code @ /projects/QCCODE
    4 QC Design @ /projects/QCDESIGN
    5 QC Reports @ /projects/QCREP
    6 Sandbox @ /projects/SAN
    7 Systemic Automation Tools @ /projects/SAT
    8 The Swamp @ /projects/SWAMP

However when I run the same 'strack' command from the standard bash (inside WebStorm or outside of WebStorm in iTerm or such) then the following output is displayed.

23:11 $ node strack -P
  - Projects

As I wrote up this question, I - like so often happens when typing up a stackoverflow question - realized the dillemma. The other call that prints out the projects themselves, is an asynchronous call, the actual app shoots off that call and then executes the remaining lines of code and finishes. Before the projects are even returned and can be printed to the console. I'm not sure what WebStorm is doing to keep the console attached to the running process but I'd love to have that work for my CLI. Any ideas, thoughts, or suggestions on how I should redesign this application to actually print out the projects to the command line?

All of the code is available on the github repo here.

like image 709
Adron Avatar asked Nov 14 '15 19:11

Adron


2 Answers

I think the issue is with your array boundaries in your while loop. data.size is probably something you're remembering from one of the 8 other languages you know, lol. BUT it's not in js, you're looking for data.length. Try this, it's trimmed down and has a mock for the scmStash object but I think you'll see what I mean:

var command, listProjects, program, scmStash;

program = require('commander');

scmStash = {
  getRepositories: function(cb) {
    return cb([
      {
        name: 'a',
        cloneUrl: 'b'
      }, {
        name: 'c',
        cloneUrl: 'd'
      }
    ]);
  },
  getProjectListing: function(cb) {
    return cb([
      {
        name: "proj1",
        link: {
          url: "http://blah"
        }
      }, {
        name: "proj2",
        link: {
          url: "http://bluh"
        }
      }
    ]);
  }
};

command = {};

listProjects = function() {
  return scmStash.getProjectListing(function(projects) {
    var i, j, len, project, results;
    results = [];
    for (i = j = 0, len = projects.length; j < len; i = ++j) {
      project = projects[i];
      results.push(console.log('    ' + i + ' ' + project.name + ' @ ' + project.link.url));
    }
    return results;
  });
};

Output:

$ node .temp/adron.js -P
  - Projects
    0 proj1 @ http://blah
    1 proj2 @ http://bluh

Also, there's an optimization to be had by storing the length of the array in a variable before iterating it but it's very minor. Worry about that when you have a million elements in an array.

like image 183
jcollum Avatar answered Oct 12 '22 02:10

jcollum


There is an ES7 recommendation for async/await syntax.

In the meanwhile, there are plenty of flow control packages available. You might consider the 'async' NPM package.

like image 2
Joe Davis Avatar answered Oct 12 '22 03:10

Joe Davis