I’m a long time PHP (CodeIgniter & WordPress) developer that only recently wanted to learn a few other languages. I’ve set out to learn Ruby (on Rails, and Sinatra), Python (w/ Flask framework) and Javascript with node.js.
I decided to create the most basic application I can think of, a URL expander, using each of these languages. I have managed to create a working version in every language, except node.js and Javascript.
I kinda know my problem, I know it is related to callbacks. I know I’m not doing it right. I get the basic idea of callbacks, but I just cannot figure out how to fix this mess I have created.
This is my whole code:
var http = require('http');
var url = require('url');
function expand() {
var short = url.parse('http://t.co/wbDrgquZ');
var options = {
host: short.hostname,
port: 80,
path: short.pathname
};
function longURL(response) {
console.log(response.headers.location);
}
http.get(options, longURL);
}
function start() {
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("Hello World");
expand();
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
start();
The server starts, and when a request is made, it calls the expand function which returns the expanded URL in the terminal. I’m trying to get it to print in the browser.
Any help is appreciated. Thanks in advance.
You’ve made a few flaws.
You should rewrite expand to pass the url in and pass a callback in. Any function that does anything asynchronous generally has the signature
(data, callback)in node. This basically allows you to say I want this function to do something then tell me when it’s done.Here the callback is expected to have the signature of
(err, data)which almost all callbacks in node have. We’ve also added error handling which is a must.We now change onRequest to actually call expand properly
Here we have added error handling logic and also unpacked the actual url to expand from the query string.
Generally the pattern of
doSomething<data, callback<err, result>>works very well in node.js.It’s the exact same as
let result = doSomething<data> mayThrow errthat you expect in your normal blocking languages except it’s asynchronous.Note that the alternative option of passing the
ServerResponseobject into the function is frowned upon, by doing so your creating unnecessary hard coupling between the expand function and the server response.The expand function should only expand an url and return the expanded url, it has no business doing IO itself.
Full code