Last active
August 29, 2015 13:57
-
-
Save jesstelford/9383044 to your computer and use it in GitHub Desktop.
Minimal node.js express example showcasing hoisting, type coercion, module patterns, closures, strict mode, and how to avoid nasty `undefined` issues.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The same as `index.js`, but in Coffeescript. Try it out here: http://michaelficarra.github.io/CoffeeScriptRedux/#try: | |
express = require 'express' | |
class Foo | |
'use strict' | |
defaultQuery = {} | |
query: undefined | |
toString: -> | |
if @query? | |
"query = #{JSON.stringify @query}" | |
else | |
"query = #{JSON.stringify defaultQuery}" | |
constructor: (q) -> | |
@query = q | |
app = express() | |
app.get '/foo', (req, resp, err) -> | |
f = new Foo req.query | |
resp.send 200, "#{f}" | |
app.listen 3000 | |
console.log "Listening to http://localhost:3000" | |
# Visit http://localhost:3000/foo?bar=zip | |
# You should see outputted: | |
# {bar: "zip"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Use npm to include the 'express' module | |
var express = require('express'); | |
// Creating a new module that we'll call 'Foo' | |
// The 'undef' parameter is not populated since where it is called (on line | |
// 47), nothing was passed. By default, this means the value of `undef` will be | |
// `undefined`. This is a protection against a malicious application changing | |
// the value of the `undefined` variable. NOTE: This isn't necessary since we're | |
// using strict mode which protects against this for us | |
var Foo = function(undef) { | |
// Force 'strict' mode to better handle errors, etc | |
'use strict'; | |
// a variable we will use later in a closure | |
var defaultQuery = {} | |
// This is a variable which will exist on any instance of this module | |
// Default it to undefined | |
Module.prototype.query = undef; | |
// Overriding the default `.toString` method of `Function` (since `Module` is | |
// a `Function`) | |
Module.prototype.toString = function() { | |
// Using loose equality, checking for `null` will also check for `undefined` | |
// ie; null == undefined is true, but null === undefined is false | |
if (this.query != null) { | |
// `this` refers to the instance of the module | |
return "query = " + JSON.stringify(this.query); | |
} else { | |
// using a variable that was closed over into this scope (since this | |
// .toString() method is a closure) | |
return "query = " + JSON.stringify(defaultQuery); | |
} | |
}; | |
// Executed when a new instance of this module is created with `new Foo()` | |
// This definition is 'hoisted' to the top of the block scope, which is what | |
// allowed us to do `Module.prototype.query = {}` above without an 'undefined | |
// reference' error. | |
function Module(q) { | |
// `this` refers to the instance of the module | |
this.query = q; | |
} | |
// This gets assigned to the variable `Foo` above | |
return Module; | |
}() | |
// Sets up a new HTTP server | |
app = express(); | |
// Add a single GET route of 'http://whatever.tld/foo' | |
// See: http://expressjs.com/3x/api.html#app.VERB | |
app.get('/foo', function(req, resp, err) { | |
// Create a new instance of 'Foo', and pass it an object, which is the query | |
// parameters of the GET request | |
var f = new Foo(); | |
// Send a response from the server | |
// Note the `'' + f` - this uses type coercion to treat `f` as a string. | |
// Since `f` isn't a string (it's an Object), it tries to get a string | |
// representation of it by calling `.toString()` automagically. ie; It calls | |
// the `.toString()` we defined in the `Foo` module above. | |
resp.send(200, '' + f); | |
}); | |
// Start the server running, listening on port 3000 | |
app.listen(3000); | |
// Just some stdout output to show we're ready to accept requests | |
console.log("Listening to http://localhost:3000"); | |
// Visit http://localhost:3000/foo?bar=zip | |
// You should see outputted: | |
// {bar: "zip"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment