Update and Coming Events

I haven’t written her for awhile and the reason is quite simple: I started a new job. In addition to that I kept the part-time minimum wage job that I was also working. Throw in the fact that part of the time I am a single dad, have a house to keep up, and am still learning programming, and you end up with a lot of stuff to do. That said, my time management skills have slipped, and now I am working on getting back on board the train. I wasted time on Instagram, ridiculous political arguments on Facebook, and getting lost in the endless articles on Medium – not to mention Bullet Journal blogs and Instagrams.

Yes, I’ve fallen into the Bullet Journal craze, but to be honest, mine is as utilitarian and minimalist as it can be. No drawings, no fancy fonts, I don’t even use a ruler. But it has helped quite a bit anyway. Things that were slipping through the cracks are now getting caught. I haven’t gotten back into the full “Getting Things Done” mode that I was a few years ago, but now I find that I actually have time, for example, to…write a blog post! So at some point I’ll do a post on how my BuJo works, and how I organize and all that stuff, but for today, let’s hit some highlights.

As noted, I landed a job, in the IT field (at last). It doesn’t have as much development or writing code as I’d like, but I’m learning a lot about networks, how systems of different software work, and what it’s like to be on call pretty much all the time(!) I’ll do a post soon on how I got the job, how Free Code Camp helped, etc.

In addition, I’ve decided to build a Fintech app. Really, it’s a toy app, something for me to play around with and learn to use some new languages and technologies, as well as mock up something that could actually be used. It will involve me learning SASS, React, ArcGIS web development and Bitcoin.JS, as well as using the knowledge I have of HTML5, CSS3, JavaScript (I may even need to learn ES6), MongoDB, Node, and Express. It’s pretty ambitious, I guess, but I can do it in pieces and slowly get up to a full scale app.

Anyway, I’ll be blogging my adventures, hopefully weekly or more, and I hope you’ll jump in for the ride!

Advertisements

Free Code Camp and Learning Express.js: What’s in Query

Next to last lesson! Note that we’re using routes here; these are very useful, and also we’ll be using them in the future quite a bit. Let’s get the Directions and Hints:

WHAT’S IN QUERY
Exercise 7 of 8

Write a route that extracts data from query string in the GET ‘/search’ URL route, e.g. ?results=recent&include_tabs=true and then outputs it back to the user in JSON format.

——————————————————————————-

## HINTS

In Express.js to extract query string parameters, we can use:

req.query.NAME

To output JSON we can use:

res.send(object)

So, we start by declaring our variables, as always:


var express = require('express');
var port = process.argv[2];
var app = express();

Next, we add the route, which is specified as “/search”. Also, we are using a get operation, per the directions. And of course, we need to listen on a port. Thus:


app.get('/search', function(req, res) {

});

app.listen(port);

In the last lesson, we used req.param.variableName to extract parameters. Here, the query string is where we want to get our parameters from. Now, I totally did it the hard way and parsed everything in my query string, then added it together and formatted it to get the answer. Oops. Anyway, to get the pieces of the query, I did this:


var results = req.query.results;
var type = req.query.type;
var page = req.query.page;

Then, using the send command in the hint, I outputted it like so:


res.send("{\"results\":\"" + results+ "\",\"type\":\"" + type +"\",\"page\":\"" + page +"\"}");

It works, and here is my final program.


var express = require('express');
var port = process.argv[2];
var app = express();

app.get('/search', function(req, res) {
var results = req.query.results;
var type = req.query.type;
var page = req.query.page;

res.send("{\"results\":\"" + results+ "\",\"type\":\"" + type +"\",\"page\":\"" + page +"\"}");
});

app.listen(port);

However, it turns out, as noted, that I did it the hard way. In the official solution, they merely retrieved the query string using


var query = req.query

And outputted it using


res.send(query)

Which is much more concise and simpler.

OFFICIAL SOLUTION:


var express = require('express')
var app = express()

app.get('/search', function(req, res){
var query = req.query
res.send(query)
})

app.listen(process.argv[2])

See you next time, for the final lesson!

Free Code Camp and Learning Express.js: Param Pam Pam

Moving right along!  We’re 3/4 of the way there now!

Let’s look at the Directions and Hints:

 PARAM PAM PAM
 Exercise 6 of 8
Create an Express.js server that processes PUT ‘/message/:id’ requests.
For instance:
    PUT /message/526aa677a8ceb64569c9d4fb
As a response to these requests, return the SHA1 hash of the current date
plus the sent ID:
    require(‘crypto’)
      .createHash(‘sha1’)
      .update(new Date().toDateString() + id)
      .digest(‘hex’)
——————————————————————————-
## HINTS
To handle PUT requests use:
    app.put(‘/path/:NAME’, function(req, res){…});
To extract parameters from within the request handlers, use:

    req.params.NAME

This one was pretty frustrating.  At one point, I had the correct answer and it didn’t work.  I ended up deleting everything and typing it all in again, and then it worked.  I figure there must have been a hidden character or something that was keeping it from working.  Who knows?  Anyway, here’s the explanation:

First, we declare the variables.  We require express, get the port from process.argv, and then set app to express() just like we have in the previous lessons in this tutorial:

var express = require('express');
var port = process.argv[2];
var app = express();

Next, we get the app.put function and set the port to listen:

var express = require('express');
var port = process.argv[2];
var app = express();


app.put('/message/:id', function(req, res){

});

app.listen(port);

 

Now, we turn to the rest of the hints, which aren’t that clear, like all the rest of the hints inall the node.js tutorials.

 

Okay, if we look at the require(‘crypto’) statement up there, you’ll see that the line that begins update() has a “+ id” in it.  We’re also supposed to return, along with the date, the SHA1 hash of the plus the sent ID.  Finally, we are told that our server will “process PUT ‘/message/:id’ requests.”.  The request comes in the form “PUT /message/526aa677a8ceb64569c9d4fb”.  Putting the clues together tells is that “id” is equal to the long string of letters and numbers “526aa677a8ceb64569c9d4fb”.

We need to pull that string of letters and numbers out and we do that with the other hint they gave us, req.params.NAME, except that obviously NAME is id.  So, we’ll call the result of that id and we have:

      var id = req.params.id;

So, now we’ll finally use the crypto statement and set it equal to a variable:

      var str = require('crypto')
            .createHash('sha1')
            .update(new Date().toDateString() + id)
            .digest('hex');

 

We defined id, of course, so now we’re good.

We still need to return this new string we created, so we’ll do that with res.send().  And then, we pass!

Here’s the final program:

var express = require('express');
var port = process.argv[2];
var app = express();


app.put('/message/:id', function(req, res){
      var id = req.params.id;
      var str = require('crypto')
            .createHash('sha1')
            .update(new Date().toDateString() + id)
            .digest('hex');
      res.send(str);
});

app.listen(port);

 

See you next time!

Free Code Camp and Learning Express.js: Stylish CSS

So we’re coming up on the end of the FreeCodeCamp ExpressJS tutorial.  This one is simple, almost too easy!

 

Here’s the directions and hints:

STYLISH CSS
 Exercise 5 of 8
Style your HTML from previous example with some Stylus middleware.
Your solution must listen on the port number supplied by process.argv[2].
The path containing the HTML and Stylus files is provided in process.argv[3] (they are in the same directory). You can create your own folder and use these:
The main.styl file:
    p
      color red
The index.html file:
    <html>
      <head>
        <title>expressworks</title>
        <link rel=”stylesheet” type=”text/css” href=”/main.css”/>
      </head>
      <body>
        <p>I am red!</p>
      </body>
    </html>
——————————————————————————-
## HINTS
To plug-in stylus someone can use this middleware:
app.use(require(‘stylus’).middleware(__dirname + ‘/public’));
Remember that you need also to serve static files.
## NOTE
For your own projects, Stylus requires to be installed like any other dependency:

    npm install stylus

Okay, let’s start by installing the stylus package.

$ npm install stylus
npm WARN package.json chat-example@0.0.0 No repository field.
npm WARN package.json chat-example@0.0.0 No license field.
stylus@0.54.5 node_modules/stylus
├── css-parse@1.7.0
├── debug@2.2.0 (ms@0.7.1)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── sax@0.5.8
├── source-map@0.1.43 (amdefine@1.0.0)

└── glob@7.0.3 (path-is-absolute@1.0.0, inherits@2.0.1, inflight@1.0.5, once@1.3.3, minimatch@3.0.0)

We want to use this package to ‘style’ the HTML file we are serving.  Stylus is middleware, which I talked about here.  Let’s set up the outline of an express app:

var express = require('express');

var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

app.listen(port);

Remember that they gave us the port and the filePath in the hints.

We are going to need to access the HTML file, and the stylus file.  This is a static HTML file, and we’ll serve it using a command we’ve seen before:

app.use(express.static(filePath||path.join(__dirname, 'public')));


Note that since we're using path.join here, we'll need to add a require statement for it:
<div>
var path = require('path');

Next, we want to take the line they gave us in the hints to get the stylus file:

app.use(require('stylus').middleware(__dirname + '/public'));

And that's really it!  Here's our final program:

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();
app.use(express.static(filePath||path.join(__dirname, 'public')));
app.use(require('stylus').middleware(__dirname + '/public'));
app.listen(port);

See you next time!

Free Code Camp and Learning Express.js: Good Old Form

Exercise number four of the FreeCodeCamp Express.js tutorial.  We’re flying right along!  Here’s the directions and hints they give us:

 GOOD OLD FORM
 Exercise 4 of 8
Write a route (‘/form’) that processes HTML form input (<form><input name=”str”/></form>) and prints backwards the str value.
——————————————————————————-
## HINTS
To handle POST request use the post() method which is used the same way as get():
    app.post(‘/path’, function(req, res){…})
Express.js uses middleware to provide extra functionality to your web server.
Simply put, a middleware is a function invoked by Express.js before your own request handler.
Middlewares provide a large variety of functionalities such as logging, serving static files and error handling.
A middleware is added by calling use() on the application and passing the middleware as a parameter.
To parse x-www-form-urlencoded request bodies Express.js can use urlencoded() middleware from the body-parser module.
    var bodyparser = require(‘body-parser’)
    app.use(bodyparser.urlencoded({extended: false}))
Read more about Connect middleware here:
The documentation of the body-parser module can be found here:
Here is how we can flip the characters:
    req.body.str.split(”).reverse().join(”)
——————————————————————————-
## NOTE
When creating your projects from scratch, install the body-parser dependency with npm by running:
    $ npm install body-parser
…in your terminal.

Again, the port to use is passed expressworks to the application as process.argv[2].

Okay, first we need to install the package as mentioned in the note.  Typing npm install body-parser at the $ prompt gives us:

npm WARN package.json chat-example@0.0.0 No repository field.
npm WARN package.json chat-example@0.0.0 No license field.
body-parser@1.15.1 node_modules/body-parser
├── content-type@1.0.2
├── bytes@2.3.0
├── depd@1.1.0
├── qs@6.1.0
├── on-finished@2.3.0 (ee-first@1.1.1)
├── raw-body@2.1.6 (unpipe@1.0.0)
├── http-errors@1.4.0 (inherits@2.0.1, statuses@1.3.0)
├── debug@2.2.0 (ms@0.7.1)
├── iconv-lite@0.4.13

└── type-is@1.6.13 (media-typer@0.3.0, mime-types@2.1.11)

This one is actually easier than it looks, because they give you everything, and I mean everything, you need to do it.

First we declare variables, noting that as usual they are supplying us the port in process.argv[2]:

var express = require("express");
var app = express();
var port = process.argv[2];
Next add the lines relevant to body-parser:
var bodyparser = require('body-parser');
app.use(bodyparser.urlencoded({extended: false}));

Add the line for the post request:

app.post('/path', function(req, res){...})

And inside the brackets goes the code for reversing the string:

     req.body.str.split('').reverse().join('');

Oh yeah….there IS one sneaky little it.  See up there in the directions where it says “Write a route (‘/form’)”?  And see how in the app.post() line it says ‘/path’?  Yeah, that gets changed.  Presto, we’ve done it!

And here’s the final program:

var express = require("express");
var app = express();
var port = process.argv[2];

var bodyparser = require('body-parser')
app.use(bodyparser.urlencoded({extended: false}))

app.post('/form', function(req, res) {
    console.log(res.send(req.body.str.split('').reverse().join('')));
});

app.listen(port);

See you next time!

Free Code Camp and Learning Express.js: Jade

Here’s the third lesson in the Express.js tutorial.  As always, there are a couple sneaky things, but overall, this isn’t that difficult.

 

NOTE:  I found this blog post to be quite helpful for this lesson:

http://webapplog.com/jade-handlebars-express/

Let’s start with the Directions and Hints:

JADE
 Exercise 3 of 8
Create an Express.js app with a home page rendered by Jade template engine.
The homepage should respond to /home.
The view should show the current date using toDateString.
——————————————————————————-
## HINTS
The Jade template file index.jade is already provided:
    h1 Hello World
    p Today is #{date}.
This is how to specify path in a typical Express.js app when the folder is ‘templates’:
    app.set(‘views’, path.join(__dirname, ‘templates’))
However, to use our index.jade, the path to index.jade will be provided as process.argv[3].  You are welcome to use your own jade file!
To tell Express.js app what template engine to use, apply this line to the Express.js configuration:
    app.set(‘view engine’, ‘jade’)
Instead of Hello World’s res.end(), the res.render() function accepts a template name and presenter data:
    res.render(‘index’, {date: new Date().toDateString()})
We use toDateString() to simply return the date in a human-readable format without the time.
——————————————————————————-
## NOTE
When creating your projects from scratch, install the jade dependency with npm.

Again, the port to use is passed by expressworks to the application as process.argv[2].

The second to last line tells us that Jade is a package and that we need to install it via the npm (Node Package Manager).  Here’s how we do that, and the ugly results we get back…

$ npm install jade
npm WARN package.json chat-example@0.0.0 No repository field.
npm WARN package.json chat-example@0.0.0 No license field.
npm WARN deprecated jade@1.11.0: Jade has been renamed to pug, please install the latest version of pug instead of jade
npm WARN deprecated transformers@2.1.0: Deprecated, use jstransformer
jade@1.11.0 node_modules/jade
├── commander@2.6.0
├── character-parser@1.2.1
├── void-elements@2.0.1
├── jstransformer@0.0.2 (is-promise@2.1.0, promise@6.1.0)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── constantinople@3.0.2 (acorn@2.7.0)
├── with@4.0.3 (acorn@1.2.2, acorn-globals@1.0.9)
├── clean-css@3.4.13 (commander@2.8.1, source-map@0.4.4)
├── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)

└── uglify-js@2.6.2 (uglify-to-browserify@1.0.2, source-map@0.5.6, yargs@3.10.0)

We’ll start with the variables.  Note that they tell us that, as before, the port and filePath will be supplied in process.argv.

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

 

We also know that we are going to listen on a port, and they give us two app.set() statements as well, giving us:

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'jade');

app.listen(port);

Finally, we’re serving a page, so we need an app.get() function, inside of which will be the page we are “rendering”.  They give us this render statement, too, and so we have:

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'jade');

app.get('/', function(req, res) {
  res.render('index', {date: new Date().toDateString()})
})

app.listen(port);

 

And………..it doesn’t work.  It keeps saying “cannot get /home”.  Yeah, I hate when I can’t get home too.  Okay, so I thought this would be an easy fix.  Remembering the first lesson, I changed the ‘/’ in the app.get statement to ‘/home’ and ran it again.

Still didn’t work.

I was a little frustrated now.  What had I missed?  I read and reread the instructions.  Then I caught it – I hadn’t used the filePath variable anywhere, so the program didn’t know where to look for the Jade file.  But the question was, where do I use it?

 

Well, see that app.set() with the path.join statement?  That looked awfully familiar from the Static exercise, where we used:

app.use(express.static(process.argv[3]||path.join(__dirname, 'public')));

 

So, I added “process.argv[3]||” to my app.use() statement and, lo and behold, the program passed!  Here’s the final program, for reference:

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

app.set('views', process.argv[3]||path.join(__dirname, 'templates'));
app.set('view engine', 'jade');

app.get('/home', function(req, res) {
  res.render('index', {date: new Date().toDateString()})
})

app.listen(port);

See you next time!

Free Code Camp and Learning Express.js: Static

Moving on, here’s the next exercise in the FreeCodeCamp Express tutorial, Static.  The directions and hints:

STATIC
 Exercise 2 of 8
Apply static middleware to serve index.html file without any routes.
Your solution must listen on the port number supplied by process.argv[2].
The index.html file is provided and usable via the path supplied by process.argv[3]. However, you can use your own file with this content:
    <html>
      <head>
        <title>expressworks</title>
        <link rel=”stylesheet” type=”text/css” href=”/main.css”/>
      </head>
      <body>
        <p>I am red!</p>
      </body>
    </html>
——————————————————————————-
## HINTS
This is how you can call static middleware:
    app.use(express.static(path.join(__dirname, ‘public’)));
For this exercise expressworks will pass you the path:

    app.use(express.static(process.argv[3]||path.join(__dirname, ‘public’)));

There were a couple sneaky parts to this one.  Let’s begin with the easy stuff.

First, we require express, and we assign process.argv[2] to port and process.argv[3] to filePath.  We also assign express() to app.  We know we’re listening on a port, so we add app.listen(port).  And here is what we have so far:

var express = require('express');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express();

/* do stuff here */

app.listen(port);

Our application is going to go between the last two lines where it says /* do stuff here */.  At first, I thought we needed the framework from the previous lesson:

app.get('/home', function(req, res) {

})

And I added the command for the static middleware in there:

app.get('/home', function(req, res) {

    app.use(express.static(process.argv[3]||path.join(__dirname, 'public')));</div>

})

Now, a couple things.  First, I assigned process.argv[3] to the variable filePath so I changed that.  The second thing was that path as in path.join(__dirname etc), was undefined.  A little googling showed me that path is a node package, so we need to require it.  That gave me:

var express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

app.get('/home', function(req, res) {
     app.use(express.static(filePath||path.join(__dirname, 'public')));
})

But that didn’t work.  A closer examination showed me that app.get() and app.use() are two different methods.  So I get rid of the app.get() framework and just left the app.use statement there:

express = require('express');
var path = require('path');
var port = process.argv[2];
var filePath = process.argv[3];

var app = express()</div>
     app.use(express.static(filePath||path.join(__dirname, 'public')));
app.listen(port);

 

Bazinga!  It worked!

And that’s it for today.  See you next time!

Free Code Camp and Learning Express.js: Hello World

This one was fairly simple, and Quincy explained it in the video that’s part of the assignment, so I won’t spend much time on it. Here are the directions and hints:

HELLO WORLD!
Exercise 1 of 8

Create an Express.js app that outputs “Hello World!” when somebody goes to /home.

The port number will be provided to you by expressworks as the first argument of the application, ie. process.argv[2].

——————————————————————————-

## HINTS

This is how we can create an Express.js app on port 3000, that responds with a string on ‘/’:


var express = require('express')
 var app = express()
 app.get('/', function(req, res) {
 res.end('Hello World!')
 })
 app.listen(3000)

Please use process.argv[2] instead of a fixed port number:

app.listen(process.argv[2])

One thing I did that Quincy didn’t was assign the port to a variable rather than just referencing process.argv[2]. As he noted, the slash sign in the call to app.get is for the root, and to go to home from the root it would be /home and we add the word home. That’s it for this one!


var express = require('express')
var port = process.argv[2];

var app = express()
app.get('/home', function(req, res) {
res.end('Hello World!')
})
app.listen(port);

And that’s it!  See you next time!

FreeCodeCamp and Learning Express.JS: Introduction

So, we’ve finally completed the Node.js tutorials and now we’re ready to move on.  The next tutorial in the Back End Development Certification sequence for FreeCodeCamp is Express.js.  What is that, you ask?

The basic explanation is this:  Express is a whole bunch of routines to do things in Node so you don’t have to write long programs with lots of code.  It’s a library, so you can call it from within Node, and it “sits on top” of the Node Server.  It’s also extensible – you can call other libraries from Express.js – and we will in the tutorials ahead.

The fancy term for Express is Middleware.  You have a whole bunch of small routines that are part of a stack, and Node’s http server hands off requests to this stack via Express, the “middleware”, which processes it, and then the stack returns a response to the Node server again and that goes on to the client.

I know that a lot of this isn’t going to make sense now; but as we go through the tutorials you’ll start to get some of it.  This tutorial was okay – I learned some from it – but I think that it could have covered things like routes a whole lot better.  We’ll come to that though.  For now, I’ll leave you with a link to the tutorial that FreeCodeCamp recommends before starting the Express.js tutorial:

 

http://evanhahn.com/understanding-express/

Also, I very highly recommend this book:

 

Express in Action: Writing, building, and testing Node.js applications by Evan Hahn

 

See you next time!

Free Code Camp and Learning Node: HTTP JSON API Server

Last exercise in learnyounode!  W00t!

There’s an awful lot of acronyms in the title for this exercise, and that’s appropriate, because this one is pretty complex.  Strap in, because this is going to be a long post!

This one was very frustrating though.  I spent an hour or more stumped because I couldn’t access the port – I was getting an error that said, “error: listen EACCES http://localhost:37243” (Mind you, the number changed each time). I was able to finally get around this by creating a new worksheet in Cloud9, installing learnyounode on it, and then doing this exercise.  I also needed to use npm install http and npm install url again, since this is a new workspace.

 

As always, directions and hints first!

HTTP JSON API SERVER (Exercise 13 of 13)
  Write an HTTP server that serves JSON data when it receives a GET request to the path ‘/api/parsetime’. Expect the request to contain a query string with a key ‘iso’ and an ISO-format time as the value.
  For example:
  /api/parsetime?iso=2013-08-10T12:10:15.474Z
  The JSON response should contain only ‘hour’, ‘minute’ and ‘second’ properties. For example:
     {
       “hour”: 14,
       “minute”: 23,
       “second”: 15
     }
  Add second endpoint for the path ‘/api/unixtime’ which accepts the same query string but returns UNIX epoch time in milliseconds (the number of milliseconds since 1 Jan 1970 00:00:00 UTC) under the property ‘unixtime’. For example:
     { “unixtime”: 1376136615474 }
  Your server should listen on the port provided by the first argument to your program.
 ─────────────────────────────────────────────────────────────────────────────
 ## HINTS
  The request object from an HTTP server has a url property that you will need to use to “route” your requests for the two endpoints.
  You can parse the URL and query string using the Node core ‘url’ module. url.parse(request.url, true) will parse content of request.url and provide you with an object with helpful properties.
  For example, on the command prompt, type:
     $ node -pe “require(‘url’).parse(‘/test?q=1’, true)”
  Documentation on the url module can be found by pointing your browser here:
  file:///home/ubuntu/.nvm/versions/node/v4.4.3/lib/node_modules/learnyounode/node_apidoc/url.html
  Your response should be in a JSON string format. Look at JSON.stringify() for more information.
  You should also be a good web citizen and set the Content-Type properly:
     res.writeHead(200, { ‘Content-Type’: ‘application/json’ })

  The JavaScript Date object can print dates in ISO format, e.g. new Date().toISOString(). It can also parse this format if you pass the string into the Date constructor. Date#getTime() will also come in handy.

The actual URL for help with URL is:

https://nodejs.org/dist/latest-v6.x/docs/api/url.html

Typing node -pe “require(‘url’).parse(‘/test?q=1’, true)” at the $ prompt gives us:

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: ‘?q=1’,
  query: { q: ‘1’ },
  pathname: ‘/test’,
  path: ‘/test?q=1’,
  href: ‘/test?q=1’ }

}

Okay, to start, we are going to need the http and url packages, so we write our require statements.  Also, although they don’t tell us, we need a port.  If you make an empty program that just says

console.log(precess.argv[2];

It will return a port number.  Note that this port number changes all the time, so don’t bother using a number.  So far, then, we have:

</div>
<div>var http = require('http');</div>
<div>var url = require('url');</div>
<div>var port = process.argv[2];</div>
<div>

A few exercises back, we did an HTTP server, and we’re going to use the skeleton from that one:

</div>
<div>var server = http.createServer(function (req, res) {&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// request handling logic... &nbsp;</div>
<div>})&nbsp;</div>
<div>server.listen(8000)</div>
<div>

We’ll change 8000 to port, of course.

Now’s where we start really digging in.  We need to parse the URL that is sent to us.  We’re going to assign the result to a variable.  The URL is specified in the request, and is accessed by req.url.  So:

</div>
<div>var reqURL = url.parse(req.url);</div>
<div>

When you parse it (see the documentation I linked to above), you can, for example, pull out the path.  We’re going to need that, so we know if it is ‘/api/parsetime ‘ or ‘/api/unixtime’.  That is done by adding a dot followed by pathname and that gives us:

</div>
<div>var reqPath = url.parse(req.url).pathname;</div>
<div>

Last, I declare a variable called timeStmp that will hold the time sent to me by the request.  We’re going to use it in different places so I need to declare it here for scope reasons.

Also, from the lesson I referenced above, we also need to add:

</div>
<div>res.end();</div>
<div>

So the program stops listening on the port or it will never end!

All right, then, here’s what we have so far:

</div>
<div>var http = require('http');</div>
<div>var url = require('url');</div>
<div>var port = process.argv[2];</div>
<div></div>
<div>var server = http.createServer(function(req,res) {</div>
<div></div>
<div>var reqURL = url.parse(req.url);</div>
<div>var reqPath = url.parse(req.url).pathname;</div>
<div>var timeStmp;</div>
<div></div>
<div>res.end();</div>
<div></div>
<div>});</div>
<div>server.listen(port);</div>
<div>

 

Now we need to start processing the requests.  This had me stumped for a bit.  The key is to note that you are going to get more than one request, and you need to execute different actions depending on which request you get.  That sounds like a job for an if statement!

 

Two if statements, in fact, one to deal with the hours/minutes/seconds request and one to deal with the unixtime request.  If the request we get is neither of these, the res.end(); statement we have in there near the end will just print a blank line.

So, we create the two if statements, which will compare the paths given to us by the requests to the ones given in the directions:

</div>
<div>if(reqPath == '/api/parsetime') {</div>
<div></div>
<div>/* do stuff */</div>
<div></div>
<div>}</div>
<div></div>
<div></div>
<div>if (reqPath == '/api/unixtime') {</div>
<div></div>
<div>/* do different stuff */</div>
<div></div>
<div>}</div>
<div>

Now, we need the time given to us by the requests to return the information they are asking for.  They are giving us something like this:

/api/parsetime?iso=2013-08-10T12:10:15.474Z

The part we need is from 2013 on.  According to the documentation, the stuff after the question mark is the query.  That includes “iso=”, which we don’t need, so we’re going to get a substring of that query string that leaves out those 4 letters, like so:

timeStmp = reqURL.query.substring(4);

This date is in ISO-format, but we can convert this to a usable date like so:

</div>
<div>var urlTime = new Date(timeStmp);</div>
<div>

For the hours/minutes/seconds request, we can easily get them now:

</div>
<div>
<div>var hours = urlTime.getHours();</div>
</div>
<div>
<div>var minutes = urlTime.getMinutes();</div>
</div>
<div>
<div>var seconds = urlTime.getSeconds();</div>
<div>

For the Unix time, we execute:

</div>
<div>var unixdate = urlTime.getTime();</div>
<div>

Finally, we have everything we need.  We must send it back via the response now.  We specify JSON format as given to us in the hints:

</div>
<div>res.writeHead(200, { 'Content-Type': 'application/json' });</div>
<div>

Next, we use res.end to send it to the requester, and we convert it to JSON format.  For the hours/minutes/seconds request:

</div>
<div>res.end(JSON.stringify( { "hour": hours,</div>
<div>                            "minute": minutes,</div>
<div>                            "second": seconds</div>
<div>  }));</div>
<div>

And for the unixtime request:

</div>
<div>res.end(JSON.stringify( { "unixtime": unixdate }));</div>
<div>

And that’s it!  We’re done!  This is the last exercise in the learnyounode tutorial, and now we’re going to move on to the Express.js tutorial next!  See you then.  In the meantime, here’s the final program:

</div>
<div>var http = require('http');</div>
<div>var url = require('url');</div>
<div>var port = process.argv[2];</div>
<div></div>
<div></div>
<div>var server = http.createServer(function(req,res) {</div>
<div></div>
<div>var reqURL = url.parse(req.url);</div>
<div>var reqPath = url.parse(req.url).pathname;</div>
<div>var timeStmp;</div>
<div></div>
<div>console.log(req.url);</div>
<div></div>
<div>if(reqPath == '/api/parsetime') {</div>
<div>  timeStmp = reqURL.query.substring(4);</div>
<div>  var urlTime = new Date(timeStmp);</div>
<div>  var hours = urlTime.getHours();</div>
<div>  var minutes = urlTime.getMinutes();</div>
<div>  var seconds = urlTime.getSeconds();</div>
<div></div>
<div>  res.writeHead(200, { 'Content-Type': 'application/json' });</div>
<div>  res.end(JSON.stringify( { "hour": hours,</div>
<div>                            "minute": minutes,</div>
<div>                            "second": seconds</div>
<div>  }));</div>
<div></div>
<div>}</div>
<div></div>
<div></div>
<div>if (reqPath == '/api/unixtime') {</div>
<div>  timeStmp = reqURL.query.substring(4);</div>
<div>  var urlTime = new Date(timeStmp);</div>
<div>  var unixdate = urlTime.getTime();</div>
<div>  console.log(unixdate);</div>
<div></div>
<div>    res.writeHead(200, { 'Content-Type': 'application/json' });</div>
<div>    res.end(JSON.stringify( { "unixtime": unixdate }));</div>
<div>}</div>
<div></div>
<div>res.end();</div>
<div></div>
<div>});</div>
<div>server.listen(port);</div>
<div>