1

I have the following function which I export to use somewhere else with the async.series method. However when I run apiCaller._get in my IDE's debugger, it returns undefined before performing the get request. The get request is executed nonetheless. However `apiCaller._get is not asynchronous and I know it needs to take a callback, however I don't understand where to call the callback.

var http = require("http");
var querystring = require("querystring");
var _ = require("underscore");

apiCaller = {};

apiCaller.token = null;

var server=http.createServer(function(req,res){});

server.listen(8080);

apiCaller._get = function (context, config, TheCallback) {

    // get the parameters for our querytring
    var oauthParams = _.pick(config, "client_id", "client_secret", "grant_type");

    // create the querystring
    var params = querystring.stringify(oauthParams);

    var options = {
        method: "GET",
        hostname: config.host,
        path: "/my/path/to/token?" + params,
        headers : {
            'Content-Type': "application/json",
            'Accept': "application/json"
        }
    };

    var _callback = function(response) {
        console.log('STATUS: ' + response.statusCode);
        console.log('HEADERS: ' + JSON.stringify(response.headers));
        var str = '';

        //another chunk of data has been recieved, so append it to `str`
        response.on('data', function (chunk) {
            str += chunk;
        });

        // error response
        response.on("error", function (error) {
            if ( !context ) {
                console.error("Something went wrong with the api response.");
                return;
            }
            context.done(new Error("Something went wrong with the api response."));
        });

        //the whole response has been recieved, so we just print it out here
        response.on('end', function () {

            apiCaller.token = JSON.parse(str).access_token;
            // we want to stop the request if token is not correct
            if ( !apiCaller.token || apiCaller.token === undefined || apiCaller.token === null ) {
                if ( !context ) {
                    console.error("Something went wrong with the token. Wrong token! Token: %s", apiCaller.token);
                    return;
                }
                console.error("Token: %s", apiCaller.token);
                context.done(new Error("Something went wrong with the token. Wrong token!"));
            }
            console.log(str);
            console.log(apiCaller.token);

        });
    };

    var request = http.request(options, _callback);

    request.on('error', function(e) {
        console.log('problem with request');
    });

    request.end();
};
1
  • apiCaller._get() IS asynchronous because it calls a bunch of asynchronous things. You would call the TheCallback from within your function when you've collected the final async result and you would pass the callback that result. Commented Apr 22, 2015 at 9:59

1 Answer 1

2

Pass in a function as the formal parameter TheCallback and call it in the end event handler for response in the _callback function.

E.g.

var _callback = function(response) {
        console.log('STATUS: ' + response.statusCode);
        console.log('HEADERS: ' + JSON.stringify(response.headers));
        var str = '';

        //another chunk of data has been recieved, so append it to `str`
        response.on('data', function (chunk) {
            str += chunk;
        });

        // error response
        response.on("error", function (error) {
            if ( !context ) {
                console.error("Something went wrong with the api response.");
                return;
            }
            context.done(new Error("Something went wrong with the api response."));
        });

        //the whole response has been recieved, so we just print it out here
        response.on('end', function () {

            apiCaller.token = JSON.parse(str).access_token;
            // we want to stop the request if token is not correct
            if ( !apiCaller.token || apiCaller.token === undefined || apiCaller.token === null ) {
                if ( !context ) {
                    console.error("Something went wrong with the token. Wrong token! Token: %s", apiCaller.token);
                    return;
                }
                console.error("Token: %s", apiCaller.token);
                context.done(new Error("Something went wrong with the token. Wrong token!"));
            }
            console.log(str);
            console.log(apiCaller.token);
            TheCallback.apply(context, arguments);
        });

UPDATE:

By using call, apply or bind, you can execute a the callback function in the context of your choice. It could be context object provided or anything else you needed. If you do not need to change the this binding for the callback execution, call it simply with TheCallback ().

Sign up to request clarification or add additional context in comments.

1 Comment

Why are you using apply? Why not call it in request.end()?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.