0

I have a question. I've been trying to figure this out for the past 3 hours now, and I have no clue as to why this isn't working how i'm expecting it to. Please know that i'm still very new to Javascript, so I apologise if anything is blatantly obvious.

With this code, i'm trying to get a bearer token from Twitter, however, return body and console.log(body) return 2 completely different things.

When I console.log(body), I get the output I expect:

{"token_type":"bearer","access_token":"#####"}

However, if I return body, I get the http request as JSON. I've pasted my code below, I hope someone will be able to help.

var request = require('request');

var enc_secret = new Buffer(twit_conkey + ':' + twit_consec).toString('base64');
var oauthOptions = {
    url: 'https://api.twitter.com/oauth2/token',
    headers: {'Authorization': 'Basic ' + enc_secret, 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
    body: 'grant_type=client_credentials'
};

var oauth = request.post(oauthOptions, function(e, r, body) {
    return body;
});

console.log(oauth)

1 Answers1

1

Async, async, async.

You cannot return the results of an asynchronous operation from the function. The function has long since returned before the asynchronous callback is called. So, the ONLY place to consume the result of your request.post() is INSIDE the callback itself and by calling some other function from within that callback and passing the data to that other function.

var oauth = request.post(oauthOptions, function(e, r, body) {
    // use the result here
    // you cannot return it
    // the function has already returned and this callback is being called
    // by the networking infrastructure, not by your code

    // you can call your own function here and pass it the async result
    // or just insert the code here that processes the result
    processAuth(body);
});

// this line of code here is executed BEFORE the callback above is called
// so, you cannot use the async result here

FYI, this is a very common learning issue for new node.js/Javascript developers. To code in node, you have to learn how to work with asynchronous callbacks like this.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks for your comment, but i'm unsure of how to do this. I need to be able to `JSON.parse(body).access_token`, then store the output in a variable, so I can call it when i'm initialising twitter. If I were to detach this function from the variable, and move the variable inside, I wouldn't be able to call that variable outside the function. How would I be able to achieve this? – Kurisu Brooks Sep 07 '15 at 06:48
  • @KurisuBrooks - The async timing is completely undetermined. The result might be available in 1 second or it might be available in 4 minutes. As such, the ONLY way to use the result is within the callback where you know it is now available. If you want to use it to initialize twitter, then you call the twitter initialization from within this callback. This may not seem like how you want to structure things, but it IS the way you have to do things with async results. – jfriend00 Sep 07 '15 at 06:55
  • I see, thanks so much. I was trying to keep my Twitter auth keys in a seperate file that didn't get committed to git when I sync'd, but it looks like it's unavoidable. I might have to look into how async works a bit more, but you've been very kind for helping. Thanks a bunch :) – Kurisu Brooks Sep 07 '15 at 06:59