##Welcome to Drupal & Node.js Training
To test test out the internet visit our class notes google doc and put in your name, your spice and what you want to do with Node and drupal. [http://bit.ly/12ERwzm](http://bit.ly/12ERwzm)
## Hello Class ```javascript console.log('Welcome!'); ```
![slides](assets/img/slides.jpg) * **[fourkitchens.github.com/train-node](http://fourkitchens.github.com/train-node)** * We use [reveal.js](http://lab.hakim.se/reveal-js/) * Use ```esc``` to get a top level view of the slides. * Feel free to open the slides in a browser locally and use them to copy code. * You can see which slide we are on from the number in the lower right.

Who we are

## What you'll walk away with * Callbacks! * You'll know why that's funny * A Socket.io app * A chance to use the Express Node.js framework. * A few strategies on how to work node into your Drupal projects.
## What we'll build A "real-time" webapp. * Pulls nodes from Drupal * Has the basis for a chat * BONUS: Pulls images from Flickr
## What we'll build ![block diagram](assets/img/client.png)
## Class outline. * Intro to node.js * Console.log * Hello World * Integrating with Drupal 1 * **Lunch** * Async programing * Using Require() *NPM & Modules* * Quick intro to Events * Integrating with Drupal 2 * Socket.io
## Frustrated? * Who here has been confused, lost, or frustrated? * Raise your hand! It's ok to be confused, lost, or frustrated! * If you are lost tell us, it's normal and you're not slowing us down. * We're here to help and enable!
## Shy?
  • So are we.
  • We have candy and will give it to you for asking questions.
![engineer](assets/img/penguin.jpg)
## What is node.js?
What is node.js?
## From Nodejs.org
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
# WAT?
Node.js is a platform built on Chrome's JavaScript runtime [...]
* Chrome's JavaScript runtime is called V8, it's one of the reasons Chrome is considered so fast. * node.js leverages V8's speed on the server!
[...] easily building fast, scalable network applications.
* Node wants to act as a message passer (more on this later).
Node.js uses an event-driven, non-blocking I/O model [...]
* Only one thing gets executed at a time, but libraries allow I/O or other intensive tasks to be executed asynchronously so the script doesn't need to wait for them to finish.
### What Makes it ### *Fast and Scaleable?* * V8 Engine * Asynchronous libraries * Event Driven.
## Why do we need another server side language/framework?
# PHP is slow.
## What do you mean by slow?
## We actually mean Drupal and we mean it's bad at concurrency.
### Why is PHP/Drupal bad at handling concurrency? * Big memory foot print. * If you need to load 100Meg of Code to deliver 4 lines of JSON. . . * Everything happens in order. * Your 100ms database call will hold up the execution of the entire process. * Your next 100ms call will do the same, etc. * Only after all the database calls have completed can we return the 4 lines of JSON.
## In node:
Everything happens in Parellel execpt for your code.
#huh?
## Imagine a King with servants * Every morning the servants line up. * One at a time they come into his throne room. * They report on what they've done. * Sometimes the king gives them more to do. * Always one at a time, so the king can focus.
## Code Please.

              var fs  = require('fs');
              var sys = require('sys');

              fs.readFile('treasure-chamber-report.txt', function readFile(report) {
                sys.puts("oh, look at all my money: "+report);
              });

              fs.writeFile('letter-to-princess.txt', '...', function writeFile() {
                sys.puts("can't wait to hear back from her!");
              });
            
### Explain the Code Please. * Code gives node 2 things to do. * Each callback gets fired one at a time * Until one callback is fired all others wait in line
### However * We don't need to wait for the file being read, to write the file. * Both System IO calls are started independently.
### Don't need to wait for one to finish before the next starts!
## Why not write non-blocking/event-driven PHP
## There are event driven Async PHP frameworks. For example: [PRADOTM](http://www.photon-project.com/)
## Libraries. * PHP libraries are primarily blocking and not event driven. * Node.js libraries are almost all non-blocking and event driven.
### What is node.js good for * Rapid prototyping * Bursty load * API glue * Queue-ish stuff * "Real-time" applications * Easy example: chat * **Message passing!**
### What is node.js NOT good for * General purpose web server * (Large) static assets * Complex systems (business logic) * Lots of processing - use C or PHP
### What We've used it for * [RSS Hub](https://github.com/elliotttf/PubHub) * [Interactive game](http://drupalpoetry.com) * Realtime video commenting * [IRC Bot](http://hubot.github.com/) * [Parsing HTML](https://github.com/tmpvar/jsdom)
### What about the community? * Welcoming community * Package manager that kicks butt * Over 16k packages * Very fast moving project * 63 Releases in the last year and half * BUT has really good test coverage * Lots of Frameworks * Drupal module
## One more thing . . .
## Share client and server side code. ![yeah](assets/img/glasses-off.gif)
## Lets get into it! ![Adventure Time](assets/img/adventuretime.png)
Your environment
## Connecting to the server * SSH into the server from your local machine

                $ ssh YOU@nodejs.4kclass.com
              
* Pro-tip: You may want to keep two terminal sessions open to the server so you can edit files while running a node process or edit two files at once in different windows.
## Editing files * Use your preferred editor on server (we like vim but won't judge if you use emacs -- but we can't help you either). * If you want to edit files locally, SFTP with the credentials you were provided

                $ sftp YOU@nodejs.4kclass.com
              
* You can also use your preferred SFTP client.
## File structure * All course code is located in
~/nodejs
* Familiarize yourself with the files and directories here, you'll be spending most of your time in the following directories:

                ~/nodejs/js101
                ~/nodejs/exercises/drupal
                ~/nodejs/exercises/server
              
## Commands you'll be using * ```cp [src] [dst]``` - to copy a file * ```mv [src] [dst]``` - to move or rename a file * ```rm [file]``` - to delete a file * ```node [file]``` - to start a node process (or just ```node``` to use the node REPL shell). * ```CTRL+C``` - to stop a node process that does not automatically exit.
## ```console.log()``` Same debugging tool you use in the browser. * Create your first app! * Make an app.js file in the _/console.log_ folder. * Add one line. . .

            console.log('Mathamatical!');
          
Now run it

            $ node app
          
![result](assets/img/consolelog.png)
## Hello World!
Hello world server
## Port Number * A unique port has been assigned to each of you, it's in the ```~/port-xxxxx``` file in your home directory. You'll need this when we start a node server. * The ```~/config.json``` file in your home directory can be used to inject settings in your node code (more on that later).
## Your first Server. ```~/nodejs/hello/app.js``` * Respond to the HTTP request with a hello world message

              var http = require('http');
              http.createServer(function hello(request, response) {
                res.writeHead(200, {'Content-Type': 'text/plain'});
                res.end('Hello World\n');
              }).listen(1337);
              console.log('Server running at http://127.0.0.1:1337/');
            
change *1337* to your port number.
#JS101
## WAT * We've secretly replaced the js101 section with a funny video. * Lets see if the class notices. * Don't worry we'll dive down into the basics after lunch. * For now lets have some fun!
## WAT [![wat](assets/img/wat.png)](assets/video/wat.mov)
A quick intro to Express
### Express * A web application framework for node.js * Provides: * Static asset handling * Dynamic router * [Connect](http://www.senchalabs.org/connect/) middleware
### Getting started * Use the ```express``` command to set up some scaffolding for a new application:

              $ cd ~/nodejs/exercies
              $ express myserver
              $ cd myserver
              $ npm install
            
### Copy your personal Config file. * We're going to make a few changes to support the application we're going to build: 1. Copy the config.js file and client directory from your home directory to the example dirctory:

                  $ cp ~/config.js ~/nodejs/exercises/myserver/config.js
                
## Edit app.js Include the config we copied by adding it after the where path is required. Don't forget to remove the ";" after require('path').

-  , path = require('path');
+  , path = require('path')
+  , config = require('./config');
            
Use the port number from the config file.

-  app.set('port', process.env.PORT || 3000);
+  app.set('port', config.port);
            
## Try it. ![express works](assets/img/express.png)
## Integrating with Drupal I
Integrating with Drupal I
## What we'll build. * We'll ping the node server with with node title * We'll create a list of Drupal nodes in our app.
### Create the Node.js Endpoint.

              app.post('/ping', function postPing(request, response){
                console.log(request.body);      // your JSON
                response.send(request.body);    // echo the result back
              });
            
### Create a Drupal module to send the title to node. 1. Stub drupal module is created already. 2. We'll put the code that talks to node in a node_view hook. 3. Hint: we'll use drupal\_json\_encode() and drupal\_http\_request() 4. Be sure to handle errors.
### Example Drupal Module code.

              $data = array('title' => $node->title);
              $data = drupal_json_encode($data);
              $uri = variable_get('ping_nodejs_uri','http://localhost:3000/ping');

              $options = array();
              $options['headers'] = array('Content-Type' => 'application/json');
              $options['method'] = 'POST';
              $options['data'] = $data;
              $response = drupal_http_request($uri, $options);

              if ($response->code != 200) {
                drupal_set_message("Got an error: " . $response->error, 'error');
              }
              else {
                drupal_set_message('Successfully contacted node server. Response was: ' . $response->data);
              }
            
## Munch on Lunch ![lunch](assets/img/alpaca-lunch.jpg)
## Asynchronous programming
Asynchronous programming
## How to stop Code-blocking ```async/``` ![log jam](assets/img/log_jam.jpg)
## Remember the King with servants? * Every morning the servants line up. * One at a time they come into his throne room. * They report on what they've done. * Sometimes the king gives them more to do. * Always one at a time, so the king can focus.
## Syncrounous example Checkout the order of the log messages.

              console.log("I'm going to read a file synchronously.");

              syncContents = fs.readFileSync(__filename);

              console.log("I'm done reading the file synchronously.");
              console.log('I read ' + syncContents.length + ' characters.');
              console.log("Now I'm ready to do the next thing.");
            
## Asynchronous Example Now see how the log messages have changed.

              console.log("I'm going to read a file asynchronously.");
              fs.readFile(__filename, function readFile(err, data) {
                asyncContents = data;
                console.log("I'm done reading the file asynchronously.");
                console.log('I read ' + asyncContents.length + ' characters.');
              });
              console.log("Now I'm ready to do the next thing.");
            
## Results ![async](assets/img/async.png)
## Why have both?
## Why have both? * Sometimes simplifies code flow. * Useful if you _need_ to stop code from executing until the operation is completed. * Generally you should ask yourself "Should this be a callback instead."
## One last note.
### Don't do complicated stuff in the event looop.

              var start = Date.now();

              setTimeout(function timeout1() {
                console.log('We started execution ' + (Date.now() - start) + 'ms ago.');

                for (var x = 0; x < 3999999999; x++) {}

                console.log('Done with timeout1().');
              }, 1000);

              setTimeout(function timeout2() {
                console.log('We started execution ' + (Date.now() - start) + 'ms ago.');
                console.log('Done with timeout2().');
              }, 2000);
            
## Keep it simple. Don't put complicated logic in the main event thread. * Long sorts/searches. * Long Math (fibbonacci sequence). * Processing lots of raw data.
### How to get around this problem: * Fork process * Hand off to other program and listen for event. * Write C * Use a queue
## Events * Lots of node functions emit events. * Events are what trigger our callbacks. * Eventually you'll write your own. [Events Explained.](http://howtonode.org/demystifying-events-in-node)
## Using ```require()```, NPM, and modules
Using require(), NPM, and modules
## ```require()``` * Used to include built in libraries, libraries from package manager and local files. * Automatically handles dependenies.

              ~/nodejs/require/modules
            
module_a.js
console.log('this is a');
module_b.js
console.log(' this is b');
main.js

              // Note the relative paths, leaving this off for libraries you
              // define is a common mistake.
              require('./module_a');
              require('./module_b')
            
```$ node main.js```
### Dependency Handling AKA Package.json

              {
                "author": "Four Kitchens  (http://fourkitchens.com/)",
                "name": "npmExample",
                "description": "An example from the world famous Four Kitchens Node.js training.",
                "version": "0.0.1",
                "homepage": "http://fourkitchens.com",
                "repository": {
                  "type": "git",
                  "url": "git://github.com/fourkitchens/train-node.git"
                },
                "engines": {
                  "node": "~0.8.8"
                },
                "dependencies": {},
                "devDependencies": {},
                "optionalDependencies": {}
              }
            
[package.json reference](http://package.json.jit.su/)

NPM

  • Node's Personal Manservant
  • Collection of over 16k community built libraries
  • Handles installation and dependencies
  • Everything from GPIO libraries to a few CMSs
## NPM Commands * npm install - install module * add -g to install at the system level. * npm install --save - installs module and adds it to your local package.json file. * npm install - installs everything from the local package.json file. * npm init - creates an empty package.json file * npm search - search for modules [NPM help (if --help is too old school for you.)](https://npmjs.org/doc/)
## Try it

              $ mkdir ~/nodejs/require/colorsExample
              $ cd ~/nodejs/require/colorsExample
              $ npm init
              $ npm install colors
            
To add a library to your package.json file at install time add --save:

              npm install --save colors
            
* Create a file called colorsExample.js in the colorsExample directory * Here's an example of using the colors library, give it a try and run the script with ```node colorsExample``` when you're done editing.

              // colorsExample.js
              var colors = require('colors');

              console.log('hello'.green); // outputs green text
            
## More fun with colors

              console.log('i like cake and pies'.underline.red) // outputs red underlined text
              console.log('inverse the color'.inverse); // inverses the color
              console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)
            
## Where does ```require()``` look for files? * Core libraries * modules in the node_modules directory * locally defined modules _if the module is prefixed with a path_ * Paths can be absolute, but this is highly discouraged, use the relative paths or package your own module. [the mystery explained](http://www.bennadel.com/blog/2169-Where-Does-Node-js-And-Require-Look-For-Modules-.htm)
## Integrating with Drupal II
Integrating with Drupal II
## Getting a list of Drupal Nodes. 1. Install and configure Services modules. 2. Create and theme a route in our app for drupal to ping.
## Install and Configure Services module. 1. It's already there, just enable it. 2. go to admin/structure/services 3. configure a rest server with endpoint "rest". 4. configure the rest server with the node resource.
## Create & theme a route to show a list of nodes. 1. Create a new Express middleware 2. Create an endpoint that uses that middleware 3. Add a template engine to Express. 4. Create a template for the page of nodes.
## Add a new library *npm install --save superagent*
## Create the Express middleware AKA route. Create file: */routes/nodes.js ![superagent](http://visionmedia.github.com/superagent/)

              var request = require('superagent');

              /**
               * Get Nodes function
               *
               */
              module.exports  = function nodes (url, fn) {
                request.get(url)
                  .end(function gotNodes(res) {
                    if (res.body) {
                      return fn(null, res.body);
                    }
                  });
              };
            
## Change to our theme engine. [handlebars](https://github.com/donpark/hbs), [hbs handlebars for Expresss](https://github.com/wycats/handlebars.js) ```npm install --save hbs``` #### add the themeing engine to our app.

-  app.set('view engine', 'jade');
+  app.set('view engine', 'html');
+  app.engine('html', require('hbs').__express);
            
## Create the layout. Renders the page. * Create the file ```/views/layout.html``` * [gist with layout](https://gist.github.com/3982145) ![handlebars layout](assets/img/handlebars-layout.png)
## Create the template Render's the content. Create the file ```/views/nodes.html``` ![handlebars template](assets/img/handlebars-node-template.png) [gist with template](https://gist.github.com/3982229)
## Add code to the app.

              app.get('/nodes', function getNodes(req, res, next) {
                nodes('http://instructor.nodejs.4kclass.com/exercises/drupal/rest/node.json', function renderNodes(err, nodes) {
                  console.log(nodes);
                  if (err) return next( err);
                  res.render('nodes', { results: nodes });
                });
              });
            
## Socket.io
Socket.io
### What is Socket.io
Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It's care-free realtime 100% in JavaScript.
#### Server

              var io = require('socket.io').listen(80);

              io.sockets.on('connection', function onConnection(socket) {
                socket.emit('news', { hello: 'world' });
                socket.on('my other event', function onMyOtherEvent(data) {
                  console.log(data);
                });
              });
            
#### Client

              var socket = io.connect('http://localhost');
              socket.on('news', function onNews(data) {
                console.log(data);
                socket.emit('my other event', { my: 'data' });
              });
            
### What you'll build ![client](assets/img/client.png) * A backend to this...
![block diagram](assets/img/block-diagram.png)
### What you'll build * A loop to fill out content in the stories region * A [socket.io server](https://github.com/learnboost/socket.io#express-3x). The client is currently aware of three entities and two events each...
### Story * story - contains a title, description, and link.

                {
                  title: 'Story title',
                  description: 'Story body text',
                  link: 'URL to the story'
                }
              
* socket.io events: * newStories - array of story objects to add to the region. * refreshStories - array of story objects to replace what's in the region with.
### Message * message - contains a name, message, and time.

                {
                  name: 'Message Author',
                  message: 'Message body text!',
                  time: new Date()
                }
              
* socket.io events: * newMessages - array of message objects to add to the region. * refreshMessages - array of message objects to replace what's in the region with.
### Image (bonus) * image - contains a picture (URL) and link.

                {
                  picture: 'URL to the image',
                  link: 'URL to where the image should be linked to'
                }
              
* socket.io events: * newImages - array of image objects to add to the region. * refreshImages - array of image objects to replace what's in the region with.
### Bonus challenges! 1. Save new stories in memory (a variable) so they are accessible to your application. 1. Save messages in memory. 1. Serve saved stories and messages to clients when they (re)connect. 1. Fetch custom stories from RSS feeds, third party APIs, or your Drupal site!
### Bonus challenges, cont 1. Fetch custom images and save them in memory. 1. Serve custom images to clients when they (re)connect. 1. Store the stories, messages, and images in either MySQL or MongoDB. Use this list to avoid creating duplicate content in case the feed re-sends an item or you need to restart your node server. * Hint: see the next set of slides for some tips on working with databases in node.
![get on with it](assets/img/get-on-with-it.jpg)
The exercises
### Where's the code?

              ~/nodejs/exercises/server/app.js
            
* This is where you'll be living for the remainder of the class. The code is highly commented. * Anything marked with ```TODO``` is a task we're going to guide the class through. * Anything with ```(bonus)``` is a bonus task that we'll guide you through if we get to it, but feel free to tackle these on your own if you complete the other tasks.
### Create some story content.

              // Keep a counter.
              var count = 0;
              /**
               * Notifies the client of new stories.
               */
              setInterval(function newStories() {
                // Increment the counter.
                count++;

                // Create some story content to send to the client.
                var newStories = [
                  {
                    title: 'New story ' + count,
                    description: 'New story text for ' + count,
                    link: 'http://fourkitchens.com'
                  }
                ];

                // Broadcast the new stories to all clients.
                io.sockets.emit('newStories', newStories);
              }, config.pollInterval || 10000);
            
### Create stories from Drupal

              /**
               * Notifies the client of new stories.
               */
              setInterval(function newStories() {
                nodes('http://instructor.nodejs.4kclass.com/rest/node.json', function gotNodes(err, nodes) {
                  if (err) { return next(err); }

                  var newStories = [];

                  nodes.forEach(function eachNode(node) {
                    newStories.push({
                      title: node.title,
                      description: node.title + ' (nid: ' + node.nid + ')',
                      link: 'http://instructor.nodejs.4kclass.com/node/' + node.nid
                    });
                  });

                  io.sockets.emit('newStories', newStories);
                });
              });
            
### Create stories from Drupal * Create new content on your Drupal site, you should see it show up on the client the next time the site is polled. * Want to make it better? Keep a variable with the nodes you've already received and only emit the new ones.
### Welcome new clients

              app.get('/messages', function getMessages(req, res) {
                var messages = [
                  {
                    name: 'Training bot',
                    message: 'Welcome to node.js training!',
                    time: new Date()
                  }
                ];

                res.json(messages);
              });
            
### Message chat

              app.post('/message', function postMessage(req, res) {
                res.writeHead(204);
                res.end();

                var newMessages = [req.body];
                io.sockets.emit('newMessages', newMessages);
              });
            
### Message chat * Try opening your client site in another browser and start sending messages! * Want to make it better? Store the new messages so you can serve chat history to new clients.
## Working with Streams
Working with streams
### Overview * As its name implies, streams are a continuous flow of information that can be diverted or processed as it comes in.
### Overview * As its name implies, streams are a continuous flow of information that can be diverted or processed as it comes in. * This is incredibly efficient, because you don't have to wait until a stream is finished before working with any data that's come in.
### Overview * As its name implies, streams are a continuous flow of information that can be diverted or processed as it comes in. * This is incredibly efficient, because you don't have to wait until a stream is finished before working with any data that's come in. * Fundumantal abstraction in node.js I/O.
### Overview * As its name implies, streams are a continuous flow of information that can be diverted or processed as it comes in. * This is incredibly efficient, because you don't have to wait until a stream is finished before working with any data that's come in. * Fundumantal abstraction in node.js I/O. * Can be readable (reading a file), writeable (HTTP response) or both TCP connection.
### Best part is. . .
### Best part is. . . . . . You are already using them.
### First code we wrote used a stream.

              var http = require('http');
              http.createServer(function hello(request, response) {
                res.writeHead(200, {'Content-Type': 'text/plain'});
                res.end('Hello World\n');
              }).listen(1337);
              console.log('Server running at http://127.0.0.1:1337/');
            
### Lets give it a shot. ```~/nodejs/streams``` * Read a file from the file system and write it out to the console.
### On the stream data event write to console.log.

              file.on('data', function(chunk){
                console.log(chunk.toString());
              });
            
### For comparison lets use readFile instead

            fs.readFile('index.html', function(err, data) {
              if (err) throw err;
              console.log(data.toString());
            });
            
### For comparison lets use readFile instead ```fs.readFile(filename, [options], callback)``` * Reads the contents of the file asyncrounsly. * [fs.readFile Docs](http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback)
### console.log the file contents using readFile().
### Now create an HTTP server using readFile

              fs.readFile('index.html', function (err, data) {
                if (err) {
                  res.statusCode = 500;
                  res.end(String(err));
                }
                else res.end(data);
              });
            
## Pipe * Method on streams that allows you to route the data from one stream to another directly * Allows for some very powerful and performat opperations. * works like the unix pipe '|' ```history | grep node```
### Server using Pipe.

              var file = fs.createReadStream('index.html');
              file.pipe(res);
            
### Adding a stream of images from flickr to our little webapp. * Helper code to get a feed from flickr and pipe into into a stream. ** https://gist.github.com/mirzu/5828095 * New emitter for images. https://gist.github.com/mirzu/5828092
## Working with Databases
Working with databases
### Overview * One of the easiest places to see asynchronous programming: 1. Application makes call to database and immediately returns to the event loop. 1. Later, database calls back with results. * For the more advanced examples in this class you'll be given the opportunity to work with a database, either MySQL or MongoDB.
### MySQL * [http://www.mysql.com/](http://www.mysql.com/) * Relational database system * If you're a Drupal developer you're probably pretty familiar with it, but the libraries we'll be using to interact with it aren't as abstracted as DBTNG. * i.e. you'll have to write actual SQL queries ಠ_ಠ
### Node.js and MySQL * We'll be using the [node-mysql](https://github.com/felixge/node-mysql) library. * ```$ npm install mysql@2.0.0-alpha3```

              var mysql = require('mysql');
              var conn = mysql.createConnection({
                host: 'localhost',
                user: 'you',
                password: 'unsafe'
              });
              conn.connect();

              conn.query('SELECT "Hello world" AS message', function selectResult(err, rows, fields) {
                if (err) {
                  throw err;
                }

                console.log(rows[0].message);
              });
              conn.end();
            
### MongoDB * [http://www.mongodb.org/](http://www.mongodb.org/) * Schemaless document store * Documents are stored as BSON which is very similar to JSON and therefore extremely convenient to work with in node.js!
### MongoDB Examples * There's not a real query language in the same sense as MySQL and since the database is schemaless you can throw whatever you like at it: ```$ mongo```

              db.test.insert({
                title: 'test',
                message: 'Hello world'
              });
              db.test.find({ title: 'test' }).pretty();
              db.test.update(
                { title: 'test' },
                { $set: { message: 'Yo dawg' } }
              );
              db.test.find({ title: 'test' }).pretty();
            
### Sub documents * One of the most useful parts of MongoDB is the ability to store "sub documents" or objects within a primary document:

              db.test.update(
                { title: 'test'},
                { $set: {
                  speaker: {
                    name: 'Elliott Foster',
                    occupation: 'Hipster Technologist',
                    interests: [
                      'JavaScript',
                      'beer',
                      'bicycles'
                    ]
                  }
                } }
              );
              db.test.find({ 'speaker.name': 'Elliott Foster' }).pretty();
            
![mind blown](assets/img/mind-blown.gif)
### Node.js and MongoDB * We'll be using the [mongode](https://github.com/milewise/mongode) library to interact with MongoDB

              var mongode = require('mongode');
              var test = mongode.connect('mongo://127.0.0.1/test');
              var collection = test.collection('test');
              var doc = { title: 'test2', message: 'node and mongo, yay!' };
              collection.insert(doc, {safe:true}, function insertResult(err, objects) {
                if (err) {
                  console.error(err.message);
                  process.exit(1);
                }
                collection.findOne({ title: 'test2' }, function findOneResult(err, document) {
                  if (err) {
                    console.error(err.message);
                    process.exit(1);
                  }
                  console.log(document.message);
                  process.exit(0);
                });
              });
            
Writing your own events
## Roll your own

              // basic imports
              var events = require('events');
              var util = require('util');

              function Poll(feed) { this.feed = feed; };
              util.inherits(Poll, events.EventEmitter);

              Poll.prototype.getStories = function(callback) {
                var self = this;

                /**
                 * Assume fetchStories grabs an array of content and
                 * executes this callback on completion.
                 */
                fetchStories(self.feed, function gotStories(err, newStories) {
                  if (!err && newStories.length) {
                    self.emit('fed', null, newStories);
                  }
                });
              };
              exports.Poll = Poll;
            
JavaScript 101
### Hashes (AKA Objects) * A hash is an object, they can contain properties:

              var awesomeCompany = {
                name: 'Four Kitchens',
                location: 'Austin, TX'
              };

              console.log(awesomeCompany.name + ' is awesome!');
            
### Hashes (AKA Objects) * They can also contain functions:

              var awesomeCompany = {
                name: 'Four Kitchens',
                location: 'Austin, TX',
                knowsNode: function() {
                  return true;
                }
              };

              if (awesomeCompany.knowsNode()) {
                console.log(awesomeCompany.name + ' knows node!');
              }
            
### Scope: Local Variable Scope

              /**
               * This function defines its own 'pet' variable that
               * will not alter the one defined in the global scope.
               */
              var example2 = function() {
                var pet = 'chupacabra';
                console.log("My function's pet is a " + pet);
              };

              console.log('Example 2: My pet is a ' + pet);
              example2();
              console.log('Now my pet is a ' + pet);
            
### Scope: Local Variable Scope ![result](assets/img/scope2.png)
## Anonymous and named functions ![spy vs spy](assets/img/spy-vs-spy.png)
## Functions in Javascript. * Functions are objects. * Functions can be passed in as arguments. * Refered to as a callback.
## Functions

              var Func = function() {
                console.trace("I'm a function.");
                console.log('==========================');
              };

              setTimeout(Func, 2000);
            
## Named functions

              setTimeout(function named() {
                console.trace("I'm named, somebody loves me.");
                console.log('==========================');
              }, 1000);
            
## Anonymous functions

              setTimeout(function() {
                console.trace("I'm anonymous, see?");
                console.log('==========================');
              }, 1);
            
## Use named functions. * Makes it easier to find what is wrong in the stack trace * Whats a stack trace?
## Stack Trace * Node outputs a list of which functions were called when your code broke * Makes it easier to find out where the error was.
## Stack Trace Example. * First we'll try using console.trace * Second we'll uncomment a real mistake and we'll see how it works. ![stacktrace](assets/img/stacktrace.png)
### This

            var unicorn = new Unicorn();
            unicorn.addHorns(1);
          
![output](assets/img/this1.png)
### Whyyy!?!? ![whyyyy](assets/img/this-wat.jpg)
### Whyyy!?!? * Remember when we said everything's an object? * The value of ```this``` changed when we entered the ```countHorns()``` function.
### Ok, let's fix it!

            /**
             * Update the Unicorn prototype to be aware of
             * the scope of 'this'.
             */
            Unicorn.prototype.addHorn = function(horns) {
              // Assign the local variable 'self' to the value of 'this' so we can still
              // access 'this' in other scopes.
              var self = this;
              self.horns = horns;

              setTimeout(function countHorns() {
                if (self.horns > 0) {
                  console.log("I'm a unicorn!");
                }
                else {
                  console.log("I have 0 horns. I must be a horse!");
                }
              }, 1);
            };
          
### This (fixed)

            var unicorn2 = new Unicorn();
            unicorn2.addHorn(2);
          
![output](assets/img/this2.png)
### Yay! ![yay](assets/img/this-yay.jpg)