Jersey Barrier

Up to this point I have managed to complete another two exercises from nodeschool.io's learnyounode package, and have 5 more packages left to complete.

I started working on the HTTP Collect exercise:

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 and the second line should contain the complete String of characters sent by the server.

and right away I hit a road block, well a jersey barrier, figuratively of course. I read the hints too procedurally, thanks computer science classes, and thought, "Wait! You are saying I have two ways to do this but I have to do it your way?!".

Here is the beginning of the hints section

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!

At first I thought, "Okay, I'll take the high road and do it without the plugin". I started and attempted to create the solution based off the previous exercise HTTP Client and tried my first go at verifying my solution learnyounode verify httpConnect.js. Off the bat, I get their lovely didn't pass error. I sat on it for a bit and re-read the instructions.

When I went over the hints again, I had an aha moment, thinking that the choice they were giving me was based on the two packages they recommended for reading streams was to install either bl or concat-stream. So I caved and went  to bl and solved the problem, after having to figure out why I couldn't include the bl package in the first place. It was along the lines that because I installed the package using npm install -g bl instead of npm install bl.

Here's my solution using bl:

	
var http = require("http");
var bl = require("bl");

http.get(process.argv[2], function(response) {
	response.pipe(bl(function(err, data) {
		console.log(data.toString().length);
		console.log(data.toString());
	}));
});
	

It still irked me that I had to even bother downloading another package for something that seemed so simple. So I went back and realized that my first go without the package could have worked, but I was so concerned with following how they wanted me to work it out, that I missed just printing out the data.length before pringting the data! If I had re-read the instructions and took a breather, the problem would have been completed much sooner.

Here's my solution without bl:

	
var http = require("http");

http.get(process.argv[2], function(response) {
	var output = "";
	response.setEncoding("utf8");
	response.on("data", function(data) {
		output += data;
	});

	response.on("end", function() {
		console.log(output.length);
		console.log(output);
	});
});
	

Overall its only six lines longer, but at the end of the day I am not having to include a whole package just to do one function. You could argue that there are benefits, but at the end of the day like the tried and tested jQuery, if you can write it yourself without having to reinvent the whole wheel you are better off using vanilla-js.

EDIT

From: maxwell ogden @denormalize

theleovander one upside to using concat-stream/bl is that you don't corrupt multibyte utf8 characters (which happens with output += data)

After looking at the bl.js repository, it looks like the buffer is piped into an Array and then Buffer is used to concat the contents, with that being said, my += solution could potentially be replaced with an Array.push() and Array.join(), but there could be more I am missing with conversions.