FreeCodeCamp and Learning Node: HTTP Collect

We’ve completed part 1 of the challenges for FreeCodeCamp’s Node section, and now we’re on to Part 2.  FreeCodeCamp broke this up into sections since the Node tutorial is pretty long.  Last time we learned about using http and the get method, and this lesson builds on that.  As always, you should try it first and then look at what I did. Let’s get right to it!

Here are the directions and hints:

HTTP COLLECT (Exercise 8 of 13)
  Write a program that performs an HTTP GET request to a URL provided to you as the first command-line argument. Collect all data from the server (not just the first “data” event) and then write two lines to the console (stdout).
  The first line you write should just be an integer representing the number of characters received from the server. The second line should contain the complete String of characters sent by the server.
 ─────────────────────────────────────────────────────────────────────────────
 ## HINTS
  There are two approaches you can take to this problem:
  1) Collect data across multiple “data” events and append the results together prior to printing the output. Use the “end” event to determine when the stream is finished and you can write the output.
  2) Use a third-party package to abstract the difficulties involved in collecting an entire stream of data. Two different packages provide a
  useful API for solving this problem (there are likely more!): bl (Buffer List) and concat-stream; take your pick!
  To install a Node package, use the Node Package Manager npm. Simply type:
     $ npm install bl
  And it will download and install the latest version of the package into a subdirectory named node_modules. Any package in this subdirectory under your main program file can be loaded with the require syntax without being prefixed by ‘./’:
     var bl = require(‘bl’)
  Node will first look in the core modules and then in the node_modules directory where the package is located.
  If you don’t have an Internet connection, simply make a node_modules directory and copy the entire directory for the package you want to use from inside the learnyounode installation directory:
  file:///home/ubuntu/.nvm/versions/node/v4.4.3/lib/node_modules/learnyounode/node_modules/bl
  file:///home/ubuntu/.nvm/versions/node/v4.4.3/lib/node_modules/learnyounode/node_modules/concat-stream
  Both bl and concat-stream can have a stream piped in to them and they will collect the data for you. Once the stream has ended, a callback will be fired with the data:
     response.pipe(bl(function (err, data) { /* … */ }))
     // or
     response.pipe(concatStream(function (data) { /* … */ }))
  Note that you will probably need to data.toString() to convert from a Buffer.
  Documentation for both of these modules has been installed along with learnyounode on your system and you can read them by pointing your browser here:
  file:///home/ubuntu/.nvm/versions/node/v4.4.3/lib/node_modules/learnyounode/docs/bl.html

  file:///home/ubuntu/.nvm/versions/node/v4.4.3/lib/node_modules/learnyounode/docs/concat-stream.html

Okay, let’s break this down step by step.  I didn’t want to have to use a bunch of appends, because that didn’t sound elegant to me.  I went with one of the third party methods instead, and I picked the Buffer List package.  You can always use the other one.

Type “npm install bl first” at the $ prompt (in other words, NOT in your program), and you’ll get:

<YOUR USERNAME>:~/workspace $ npm install bl
npm WARN package.json chat-example@0.0.0 No repository field.
npm WARN package.json chat-example@0.0.0 No license field.
bl@1.1.2 node_modules/bl
└── readable-stream@2.0.6 (string_decoder@0.10.31, process-nextick-args@1.0.7, util-deprecate@1.0.2, inherits@2.0.1, core-util-is@1.0.2, isarray@1.0.0)

Now Buffer List is installed and you can use it!

Time to start the program.  This is going to use the get method of http again, so we can borrow from the last exercise.  We also need to require the bl package as noted in the hints.  I left require fs in there but you don’t need it for this exercise.

var bl = require('bl');
var fs = require('fs');
var http = require('http');
var addr = process.argv[2];
Remember that the third element of process.arg is the path to the data we want.  That takes care of the variables and requires, so let’s move on to the rest of the program.
http.get(addr, function callback(response) {

&amp;nbsp; &amp;nbsp; &amp;nbsp;/* Do stuff here */

}).on('error', (e) =&amp;gt; {
&amp;nbsp; console.log(`Got error: ${e.message}`);
});

The framework of the program hasn’t changed.  What IS going to change is the part where I put “/* Do stuff here */”. I put the line in the hint in there:

response.pipe(bl(function (err, data) { /* ... */ }))&amp;nbsp;

Just for fun I put

console.log(data.length);

in there, and got a warning that it expected an error to be handled.  From one of the previous lessons, I remembered that we add:

if(err)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);

I ran it then, even though it’s incomplete, and lo and behold I got a length back that matched the expected answer!  Almost there!  Now, the next thing is to print the contents of the buffer, and they tell you how to do that with a little hint that you need to convert it to a string, like so:

console.log(data.toString());

Do that, and the program passes!

 

Just a quick aside:  It actually took me a half hour and several false trails before I got this.  Believe me, I’m making it seem much easier than it was here!

Anyway, here’s the entire program!

var bl = require('bl');
var fs = require('fs');
var http = require('http');
var addr = process.argv[2];

http.get(addr, function callback(response) {

response.pipe(bl(function (err, data) {
if(err)
console.log(err);

console.log(data.length);
console.log(data.toString());

}))


}).on('error', (e) => {
console.log(`Got error: ${e.message}`);
});
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s