Anthony
Anthony

Reputation: 14269

How to pass callback as variable to predefined callback

I have some code written in LiveScript (fork of Coffeescript) that will make a request using the request module, and then pass the statusCode of the response to a callback.

url = 'http://www.google.ca'

logCode = (statusCode) ->
  console.log statusCode

makeRequest = (url, callback) ->
  request url, (err, response, body) ->
    if body
      callback response.statusCode
    else
      console.log "No response"

makeRequest url, logCode

This works as expected, and the callback is triggered successfully and '200' is logged to the console.

However, I would like to make my code as clean as possible, and pull out any nested callbacks. Therefore I define a function to act as my request callback and pass it in as the second argument to request.

url = 'http://www.google.ca'

requestCallback = (err, response, body) ->
  if body
    callback response.statusCode
  else
    console.log "No response"

logCode = (statusCode) ->
  console.log statusCode

makeRequest = (url, callback) ->
  request url, requestCallback

makeRequest url, logCode

However, running this of course returns an error saying that callback is not defined. This of course makes perfect sense, as in the scope that requestCallback operates, there is no function named callback, and it cannot access the callback defined in makeRequest.

From what I've read, I can declare requestCallback inside an anonymous function, which will allow it to have callback passed into it. I've tried this is every manner I could conceive of without fruition.

Also, there seems to be the option of binding requestCallback to the scope of makeRequest, however I was unable to do this today as well despite my best efforts and wrangling.

How can I allow requestCallback to be aware of the callback function passed to makeRequest?

Upvotes: 0

Views: 153

Answers (1)

Halcyon
Halcyon

Reputation: 57729

Not sure how you would write it in LiveScript but in JavaScript its:

function makeRequest(url, callback) {
    request(url, function (err, response, body) {
        requestCallback(err, response, body, callback);
    });
}

So basically the callback you pass into request calls requestCallback with another argument.

If you're doing a lot of asynchronous stuff it's worthwhile to look into Promises. They can really help with avoiding callback-spaghetti.

With Promises you could do something like:

makeRequest(url).done(function (response, body) {
    if (body) {
        logCode(response.statusCode)
    } else {
        console.log("No response");
    }
}).fail(function (response) {
    throw new Error("uhoh!");
});

Upvotes: 2

Related Questions