Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You've made a few flaws.</p> <p>You should rewrite expand to pass the url in and pass a callback in. Any function that does anything asynchronous generally has the signature <code>(data, callback)</code> in node. This basically allows you to say I want this function to do something then tell me when it's done.</p> <pre><code>function expand(urlToParse, callback) { // note we pass in the url this time var short = url.parse(urlToParse); var options = { host: short.hostname, port: 80, path: short.pathname }; // note we store the clientRequest object temporarily var clientRequest = http.get(options, extractRealURL); // Always attach the error handler and forward any errors clientRequest.on("error", forwardError); function extractRealURL(res) { callback(null, res.headers.location); } function forwardError(error) { callback(err); } } </code></pre> <p>Here the callback is expected to have the signature of <code>(err, data)</code> which almost all callbacks in node have. We've also added error handling which is a must.</p> <p>We now change onRequest to actually call expand properly</p> <pre><code>function onRequest(request, response) { // parse the incoming url. true flag unpacks the query string var parsedUrl = url.parse(request.url, true), // extract the querystring url. // http://localhost:8888/?url=http://t.co/wbDrgquZ urlToExpand = parsedUrl.query.url; // call expand with the url and a callback expand(urlToExpand, writeResponse); function writeResponse(error, newUrl) { // handle the error case properly if (error) { response.writeHead(500, { 'Content-Type': 'text/plain'}); // early return to avoid an else block return response.end(error.message); } response.writeHead(200, { 'Content-Type': 'text/plain'}); // write the new url to the response response.end(newUrl); } } </code></pre> <p>Here we have added error handling logic and also unpacked the actual url to expand from the query string.</p> <p>Generally the pattern of <code>doSomething&lt;data, callback&lt;err, result&gt;&gt;</code> works very well in node.js. </p> <p>It's the exact same as <code>let result = doSomething&lt;data&gt; mayThrow err</code> that you expect in your normal blocking languages except it's asynchronous.</p> <p>Note that the alternative option of passing the <code>ServerResponse</code> object into the function is frowned upon, by doing so your creating unnecessary hard coupling between the expand function and the server response.</p> <p>The expand function should only expand an url and return the expanded url, it has no business doing IO itself.</p> <p><a href="https://gist.github.com/1493631" rel="noreferrer">Full code</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload