Skip to content

Personal Notes

David Tromblee edited this page Jan 16, 2019 · 8 revisions

Really cool way to turn code todos into github issues.

In order to run node debugging in Chrome dev tools (because they share the V8 engine)

node --inspect-brk <file-name>

When using require, module.exports can be an object of properties or just a single property

  • Good programming pattern is to declare a single class and just export that
// Thing.jsclass Thing {}
module.exports = Thing;
// App.js
const Thing = require('./Thing.js');
let stuff = new Thing();

Callback handling queue callback execution until the all other synchronous occur

  • simplest example * all statements will run in apps js * any callbacks are queued * all statement are run; each callback pulled into execution * complete all callback statement and repeat for all remaining callbacks
  • waiting to see how this works with non-blocking

Non ES6 'Class' construction

// Initialize Object, includes 'constructor'
let Car = function(make, model, year) {  
  this.make = make,  
  this.model = model,  
  this.year = year;  
  this.durability = 100;
}
// Create 'Static Methods' by creating function property directly against the object
Car.evaluate = function(car) {
  // Do some nifty evaluation and return
  return `Nice ${car.year} ${car.make} ${car.model}!`;
}
// Create Instance Methods by extending the object's prototype
Car.prototype.doWheelie = function() {
  this.durability -= 2;
  return 'Weeeeeeee!';
}

NPM Installation Tips

  • When installing new modules, it's preferred to add the --save or --save-dev flags

  • These will add the module as dependencies for the project, so that the node_modules folders can be excluded from being saved in the project source control

    • --save will add config to ensure module is always installed
    • --save-dev will add config to only install module for development purposes (testing tools etc)
  • Additionally, for production facing projects it's a good idea to include the module version number, as 'latest' will inevitably lead to module apis changing and causing all sorts of unexpected chaos

    • instead, just upgrade as needed, making sure to read up on any required refactors

Effective Commandline Support for Node App

  • yargs is a super easy to use module to process commandline arguments
  • see the below example of how to set up and use
const yargs = require('yargs');
const titleOptions = {
  describe: 'Title of note',
  demand: true,
  alias: 't'};

const bodyOptions = {
  describe: 'Body of note',
  demand: true,
  alias: 'b'
};

const argv = yargs
  .command('add', 'Add a new note',
    {
      title: titleOptions,
      body: bodyOptions
    }
  )
  .help()
  .argv;

var command = argv._[0];

if (command === 'add') {
  var note = notes.addNote(argv.title, argv.body);

  if (note) {
    console.log('Note created');
    notes.logNote(note);
  } else {
  console.log('Note title taken');
}

// Use: `node app.js add -t="A title" --body="Some Body (to love)"`

Express.js

Super simple js server framework

Important Notes

  • needs additional npm library body-parser in order to automatically parse JSON objects in the request.body property
const express = require('express');
const bodyParser = require('body-parser');

const UserService = require('./classes/user-service');

var app = express();
var port = 3000;

var userService = new UserService();

// Register middleware
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // Enable JSON body support

app.get('/users', (req, res) => {
  res.send(JSON.stringify(userService.getUsers(), null, 3));
});
  • Routes/endpoints can be directly defined against the express app, or delegated to a router instance, which is super useful for abstracting out RESTful endpoints
// router.js
const express = require('express');
let router = express.Router();

router.get('/', (req, res) => {
  res.send('No user for you!'));
});

module.exports = router;

// server.js

const express = require('express');
const userRouter = require('./userRouter');

let app = express();
app.use('/user', userRouter);
  • cookies also need a third party npm package cookie-parser

Testing with Mocha

  • install mocha globally and/or as a devDependency
  • configure npm package.json build config
    • specify where to look for files using glob syntax
{
  "test": "mocha **/*.test.js"
}

MongoDB

Start mongo server from cmd prompt on windows (git bash wont work)

// Default Directory
C:\Program Files\MongoDB\Server\4.0\bin

// Executable to start mongo instance
C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe

// Full Run Commandline
"C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe" --dbpath=C:\Users\dtrom\mongo-data\

// Executable to run interpreted commands
C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe

RoboMongo (or Robo 3T) is GUI tool for MongoDb, essentially works like most other DB GUI tools

Mongo Lingo

Data Structure

  • Database -> Collection -> Document
    • Collection is roughly equivalent to a table in relational db
    • Document is roughly equivalent to a row

Mongoose

  • data wrapper and util library for mongo

When defining a model, the name will be expected to be the singular version of the (by default plural) Collection name in the db

Basic CRUD Endpoint handling

router.get('/', (req, res) => {
  Todo.find({})
    .then((results) => {
			// Query Success Case -> 200
      res.send({results});
    }, (err) => {
			// Query Bad Return Case -> 404
      res.status(404).send(err);
    })
    .catch((err) =>  {
			// Any Other Errors -> 400
      res.status(400).send(err);
    });
}	);

Important Random Mongo Issues

  • Make sure to set the localhost connection string to 127.0.0.1 instead of just localhost
  • When creating a collection with index constraints (particulary unique), make sure to call .ensureIndexes() on the instantiated model variable

Notes on Native JS Promises

Basic Promise Syntax

let p = new Promise((resolve, reject) => {
	if (/* some conditions are met */ true) {
		resolve(/* some value or empty */'success');
	} else {
		reject(/* some value or empty */'failure');
	}
});

If a promise is return (either by being explicitly declared and return or as an expected returnable from a library/framwork), then can be called and/or changed on the Promise

// Assuming above promise definition
p.then((successData) => {
	// Either return a value or an explicit promise resolve called
	return successData || Promise.resolve(successData);

	// Or reject by either throw-ing an Error or calling promise reject directly
	throw new Error('See you in the next then\'s reject callback!');
	return Promise.reject('See you in the next then\'s reject callback!');
}, (errorOrFailData) => {

})
// Chained then acting on the result of the previous then
.then((successData) => {
	// Do something on success state
}, (errorOrFailData) => {
	// Do something on fail state
});

Clone this wiki locally