Skip to content

Instantly share code, notes, and snippets.

@knbknb
Last active November 18, 2018 10:11
Show Gist options
  • Save knbknb/947b515a4de9ea89edcae2f8a254cb21 to your computer and use it in GitHub Desktop.
Save knbknb/947b515a4de9ea89edcae2f8a254cb21 to your computer and use it in GitHub Desktop.
a TODO-list CLI app implemented using only builtin node modules (EventEmitter, process, readline)

Run the app on the command line with: node client.js. This implicitly loads server.js.

From Samir Buna's "Advanced NodeJS" course on Pluralsight

client.js

const EventEmitter = require('events');
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const client = new EventEmitter();
const server = require('./server')(client);


server.on('response', resp => {
  process.stdout.write('\u001B[2J\u001B[0;0f');//clear terminal
  process.stdout.write(resp);
  process.stdout.write('\n> '); // simple prompt >
});

let command;
let args;

rl.on('line', input => {
  [command, ...args] = input.split(' '); // for add(), delete() methods inside server
  client.emit('command', command, args);
});

server.js

const EventEmitter = require('events');

class Server extends EventEmitter {
  constructor(client) {
    super();
    this.tasks = {};
    this.taskId = 1;
    // wait for next .on() listener inside client to be defined
    process.nextTick(() => {
      this.emit('response', 'Type a command (help to list commands)');
    });

    client.on('command', (command, args) => {
      switch (command) {
      case 'help':
      case 'add':
      case 'ls':
      case 'delete':
        this[command](args); //see functions below
        break;
      default:
        this.emit('response', 'Unknown command...');
      }
    });
  }

  tasksString() {
    return Object.keys(this.tasks)
      .map(key => `${key}: ${this.tasks[key]}`)
      .join('\n');
  }

  help() {
    this.emit('response', 'Available Commands:\n add task\n ls\n delete :id');
  }
  add(args) {
    this.tasks[this.taskId] = args.join(' ');
    this.emit('response', `Added task ${this.taskId}`);
    this.taskId++;
  }
  ls() {
    this.emit('response', `Tasks:\n${this.tasksString()}`);
  }
  delete(args) {
    delete this.tasks[args[0]];
    this.emit('response', `Deleted task ${args[0]}`);
  }
}

module.exports = client => new Server(client);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment