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
console.log('Welcome!');
A "real-time" webapp.
V8 Engine
Asynchronous libraries
Event Driven.
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!");
});
For example: PRADOTM
$ ssh YOU@nodejs.4kclass.com
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.
~/nodejs
~/nodejs/js101 ~/nodejs/exercises/drupal ~/nodejs/exercises/server
Same debugging tool you use in the browser.
console.log('Mathamatical!');
Now run it
$ node app
~/nodejs/hello/app.js
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.
$ cd ~/nodejs/exercies $ express myserver $ cd myserver $ npm install
$ cp ~/config.js ~/nodejs/exercises/myserver/config.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);
app.post('/ping', function postPing(request, response){
console.log(request.body); // your JSON
response.send(request.body); // echo the result back
});
$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);
}
async/
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.");
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.");
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);
Don't put complicated logic in the main event thread.
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
{
"author": "Four Kitchens (http://fourkitchens.com/)"@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": {}
}
@fourkitchens.com>
$ 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
// colorsExample.js
var colors = require('colors');
console.log('hello'.green); // outputs green text
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)
npm install --save superagent
Create file: */routes/nodes.js
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);
}
});
};
handlebars, hbs handlebars for Expresss
npm install --save hbs
- app.set('view engine', 'jade');
+ app.set('view engine', 'html');
+ app.engine('html', require('hbs').__express);
Renders the page.
Render's the content.
Create the file /views/nodes.html
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 });
});
});
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);
});
});
var socket = io.connect('http://localhost');
socket.on('news', function onNews(data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
{
title: 'Story title',
description: 'Story body text',
link: 'URL to the story'
}
{
name: 'Message Author',
message: 'Message body text!',
time: new Date()
}
{
picture: 'URL to the image',
link: 'URL to where the image should be linked to'
}
~/nodejs/exercises/server/app.js
// 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);
/**
* 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);
});
});
app.get('/messages', function getMessages(req, res) {
var messages = [
{
name: 'Training bot',
message: 'Welcome to node.js training!',
time: new Date()
}
];
res.json(messages);
});
app.post('/message', function postMessage(req, res) {
res.writeHead(204);
res.end();
var newMessages = [req.body];
io.sockets.emit('newMessages', newMessages);
});
. . . You are already using them.
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/');
~/nodejs/streams
file.on('data', function(chunk){
console.log(chunk.toString());
});
fs.readFile('index.html', function(err, data) {
if (err) throw err;
console.log(data.toString());
});
fs.readFile(filename, [options], callback)
fs.readFile('index.html', function (err, data) {
if (err) {
res.statusCode = 500;
res.end(String(err));
}
else res.end(data);
});
history | grep node
var file = fs.createReadStream('index.html');
file.pipe(res);
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
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();
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();
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();
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);
});
});
// 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;
var awesomeCompany = {
name: 'Four Kitchens',
location: 'Austin, TX'
};
console.log(awesomeCompany.name + ' is awesome!');
var awesomeCompany = {
name: 'Four Kitchens',
location: 'Austin, TX',
knowsNode: function() {
return true;
}
};
if (awesomeCompany.knowsNode()) {
console.log(awesomeCompany.name + ' knows node!');
}
/**
* 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);
var Func = function() {
console.trace("I'm a function.");
console.log('==========================');
};
setTimeout(Func, 2000);
setTimeout(function named() {
console.trace("I'm named, somebody loves me.");
console.log('==========================');
}, 1000);
setTimeout(function() {
console.trace("I'm anonymous, see?");
console.log('==========================');
}, 1);
var unicorn = new Unicorn(); unicorn.addHorns(1);
/**
* 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);
};
var unicorn2 = new Unicorn(); unicorn2.addHorn(2);