# Getting response with NodeJS request module

**URL:** <https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020>\
**Category:** API\
**Created:** [July 12, 2017, 10:37pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020 "2017-07-12T22:37:58Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mszauer](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@Mszauer](https://discuss.dev.twitch.com/u/Mszauer)\
**Post date:** [July 12, 2017, 10:37pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/1 "2017-07-12T22:37:58Z")

</div>

Hi everyone,  
I just started using the twitch kraken api and I have a few questions. Whenever I attempt to get the json object  
there is no response. I am attempting to run this function through amazon aws lambda, and don’t have access to a console. In the code below my callback function will always print out “SUCCESS got streamers ERROR”. I am pretty certain right now the “ERROR” comes from my initial setting of result. How come result does not get changed into the proper json?  
BTW I have used postman and it returns the proper thing with the query and param, and headers

```
function getJSON(callback){
    var result = "ERROR";
    request.get(url(games[0]),function(error,response,body){
        var d = body;
        result = d.streams[0];//.channel.display_name;
        // for(var i = 0; i < limit; i++){
        // streamers.push(d.streams[i].channel.display_name)
        // }
        streamers.push(result);
    });
    if (streamers.length < 0){
        callback("ERROR");
    }else{
        callback("SUCCESS got streamers " + result);
    }
}
function url(game){
    return {
        url: "https://api.twitch.tv/kraken/streams/",
        qs : {
            'game' : 'overwatch',
            'limit' : 2
        }
        headers: {
            'Client-ID': clientID,
            'Accept': 'application/json',
            'Accept-Charset': 'utf-8',
        },
        json: true
    };
}
```

---

<div class="post-metadata">

**Author:** ![Dist](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/dist/32/7192_2.png) [@Dist](https://discuss.dev.twitch.com/u/Dist)\
**Post date:** [July 12, 2017, 10:52pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/2 "2017-07-12T22:52:30Z")

</div>

The result doesn’t get changed into JSON because no where in your code are you parsing it. What you get back from the request is just a string, to get the JSON what you’re have to do is something along the lines of:

```auto
try {
    result = JSON.parse(body);
} catch (err) {
    // if there is an error during parsing, such as the body not being JSON, it'll be caught here,.
}

```

---

<div class="post-metadata">

**Author:** ![Mszauer](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@Mszauer](https://discuss.dev.twitch.com/u/Mszauer)\
**Post date:** [July 12, 2017, 10:58pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/3 "2017-07-12T22:58:34Z")

</div>

Thank you for the reply Dist,  
Before some refactoring I had the following  
`var d=JSON.parse(body);`  
but the result were the same as now with the output being “SUCCESS got streamers ERROR”.  
Since your comment I have switched back to that way, because using json:true was not working either.  
Could this be because of it trying to execute before getting a response back?

Current code:

```
function getJSON(callback){
    var result = "ERROR";
    request.get(url(games[0]),function(error,response,body){
        console.log("requested for url: " + url(games[0]));
        var d = JSON.parse(body);
        result = d.streams[0];//.channel.display_name;
        // for(var i = 0; i < limit; i++){
        // streamers.push(d.streams[i].channel.display_name)
        // }
        streamers.push(result);
    });
    if (streamers.length < 0){
        callback("ERROR");
    }else{
        callback("SUCCESS got streamers " + result);
    }
}

function url(game){
    return {
        url: "https://api.twitch.tv/kraken/streams/",//twitchlimit,
        qs : {
            'game' : 'overwatch',
            'limit' : 2
        },
        headers: {
            'Client-ID': clientID,
            'Accept': 'application/json',
            'Accept-Charset': 'utf-8',
        }
    };
}
```

---

<div class="post-metadata">

**Author:** ![Dist](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/dist/32/7192_2.png) [@Dist](https://discuss.dev.twitch.com/u/Dist)\
**Post date:** [July 12, 2017, 11:06pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/4 "2017-07-12T23:06:02Z")

</div>

> [@Mszauer](#):
>
> Could this be because of it trying to execute before getting a response back?

Yes. request is an async function so while it is waiting for a response from the server, the rest of your code will keep on executing, in this case your callback.

move this

```auto
if (streamers.length < 0){
    callback("ERROR");
}else{
    callback("SUCCESS got streamers " + result);
}

```

inside of the callback being passed to request.get, this will mean that if-else statement wont get run until request receives the response.

And in your current code, make sure to wrap the JSON.parse() in a `try { ... } catch(err) { }` because there will be times where the response is malformed, an error, etc… and this can kill a program if you’re not catching it.

---

<div class="post-metadata">

**Author:** ![Mszauer](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@Mszauer](https://discuss.dev.twitch.com/u/Mszauer)\
**Post date:** [July 13, 2017, 12:46am UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/5 "2017-07-13T00:46:36Z")

</div>

I have implemented you suggestions and it seems to have worked a bit. I ended up putting the json.parse into a try/catch block, and moved the if/else statements inside the getJSON method. However, now I don’t get any output.

This is how I am invoking the getJSON method:

```
function handleGameResponse(intent,session,callback){
    //gets the game
    var game = intent.slots.game.value;
    if (!games.includes(game)){
        var speechOutput = "You asked for: " + intent.slots.game.value;
        //var speechOutput = "You asked for: " + games[game] + " That game is currently not an option. These are your current options: " + arrayToString(games)
        var repromptText = "Please ask one from the current options.";
        var header = "Invalid Game";

    }else {
        getJSON(function(data){
            if(data !== "ERROR"){
                var speechOutput = data; //capitalizeFirst(game) + " top three streamers are: " + arrayToString(streamers) + '.';
                var repromptText = "Do you want to hear more about games?";
                var header = capitalizeFirst(game);
            }else{
                var speechOutput = "I'm sorry, something went wrong and I could not get the streamers.";
            }
            //speechOutput = data;
        });
        //speechOutput = games[0] + " games[0], game= " + game; //this executes so the getJSON isn't executing
    }
    var shouldEndSession = false;
    callback(session.attributes,buildSpeechletResponse(header,speechOutput,repromptText,shouldEndSession));
}

```

Does the above execute the same way,? As in the shouldEndSession and callback execute before the getJSON has time to give a response? I’ve read things about using a .then would that be applicable here

For ref, this is the getJSON method now:

```
function getJSON(callback){
    var result = "ERROR";
    request.get(url(games[0]),function(error,response,body){
        try{
            var d = JSON.parse(body);
        } catch (err){
            callback("Sorry, something seems to have malfunctioned while getting the streamers");
        }
        result = d.streams[0].channel.display_name;
        // for(var i = 0; i < limit; i++){
        // streamers.push(d.streams[i].channel.display_name)
        // }
        streamers.push(result);
        if (streamers.length <= 0){
            callback("ERROR");
        }else{
            callback("SUCCESS got streamers " + result);
        }
    });
}
```

---

<div class="post-metadata">

**Author:** ![Dist](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/dist/32/7192_2.png) [@Dist](https://discuss.dev.twitch.com/u/Dist)\
**Post date:** [July 13, 2017, 1:23am UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/6 "2017-07-13T01:23:18Z")

</div>

With the way you have it set up at the moment, when `handleGameResponse` is called and gets to the getJSON part, it will  
call getJSON and pass the function you’ve provided as an argument, but still continue on with the `var shouldEndSession = false; callback(session.attributes,buildSpeechletResponse(header,speechOutput,repromptText,shouldEndSession));` as none of the code in the function you’ve passed getJSON gets executed until after it receives a response.

Using `.then` requires a promise library, or modules that have it built in, I would recommend getting a good understanding of the program flow and callbacks first. You also should be careful of where you’re declaring your variables. for example say the getJSON works but the data is an error, then you have the issue that your `callback(...` function is being passed arguments that haven’t been declared, as only speechOutput has been declared in that part.

What you might find easier to manage is as regardless of success or failure you’re using the same variables speechOutput, repromptText, header etc…, you could initialise them at the start of function, even just `var header = ''` and then later in the code you can simply do `header = "Invalid Game"; and not have to use`var` to declare it each time, and will also ensure that undefined variables aren’t trying to be passed to anything.

---

<div class="post-metadata">

**Author:** ![Mszauer](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@Mszauer](https://discuss.dev.twitch.com/u/Mszauer)\
**Post date:** [July 13, 2017, 1:34am UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/7 "2017-07-13T01:34:16Z")

</div>

Thank you for the help Dist. I do realize that async operations are a weakpoint of mine and am doing this project to get better at it. It’s still in rough stages and unoptimized, I just wanted the functionality to work. I’m going to look into the request-promise npm module, as it can handle this type of thing better than the request module I am using now.

---

<div class="post-metadata">

**Author:** ![Alca](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/alca/32/2783_2.png) [@Alca](https://discuss.dev.twitch.com/u/Alca)\
**Post date:** [July 13, 2017, 5:14am UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/8 "2017-07-13T05:14:33Z")

</div>

The `request` module is really powerful. Here’s an example of a function:

```javascript
const request = require('request');

// Get config

const krakenDefaults = {
		baseUrl: 'https://api.twitch.tv/kraken/',
		headers: {
			Accept: 'application/vnd.twitchtv.v5+json',
			'Client-ID': config.twitch.api.clientID
		},
		json: true
	};

const kraken = request.defaults(krakenDefaults);

function usernameToUser(username, callback) {
	// Caching here

	return kraken({
		url: 'users',
		qs: { login: username },
		callback: (err, { statusCode }, { _total, users }) => {
			if(err || statusCode !== 200 || _total === 0) {
				callback(err, null);
			}
			else {
				callback(null, users[0]);
			}
		}
	});
}

```

You can find all of the `request` library options [here](https://github.com/request/request#requestoptions-callback).

```javascript
let input = 'alca';
usernameToUser(input, (err, data) => {
	if(err) {
		console.log('ERR', err);
	}
	else {
		console.log(input, 'is ID', data._id); // 'alca is ID 7676884'
	}
});

```

* * *

With [request-promise](https://www.npmjs.com/package/request-promise) this would look like:

```auto
const rp = require('request-promise');

// Get config

const krakenDefaults = {
		baseUrl: 'https://api.twitch.tv/kraken/',
		headers: {
			Accept: 'application/vnd.twitchtv.v5+json',
			'Client-ID': config.twitch.api.clientID
		},
		json: true
	};

const kraken = rp.defaults(krakenDefaults);

function usernameToUser(username) {
	// Caching here

	return kraken({
		url: 'users',
		qs: { login: username }
	})
	.then(({ _total, users }) => {
		if(_total === 0) {
			return null;
		}
		return users[0];
	});
}

```

```javascript
let input = 'alca';
usernameToUser(input)
	.then(data => {
		console.log(input, 'is ID', data._id); // 'alca is ID 7676884'
	});

```

And then there’s options like “`simple`” and “`resolveWithFullResponse`” that you might want.

---

<div class="post-metadata">

**Author:** ![Mszauer](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@Mszauer](https://discuss.dev.twitch.com/u/Mszauer)\
**Post date:** [July 13, 2017, 4:50pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/9 "2017-07-13T16:50:09Z")

</div>

Hey guys I really appreciate everyones help! I finally got this solved 🙂 !!!  
Implementing the request-promise module and using the .then() helped a lot  
I also implemented default values for the responses that get overwritten in the game request.  
Code:

```
function getJSON(callback){
    var options = {
        uri: 'https://api.twitch.tv/kraken/streams/',
        qs: {
            game: 'overwatch',
            limit: 2
        },
        headers: {
            Accept: 'application/vnd.twitchtv.v5+json',
            'Client-ID': clientID
        },
        json: true // Automatically parses the JSON string in the response 
    }
    rp(options)
    .then(function (jsonResponse) {
        var result = jsonResponse.streams[0].channel.display_name;
        streamers.push(result);
        if (streamers.length <= 0){
            callback("ERROR");
        }else{
            callback("SUCCESS got streamers " + result);
        }
    })
    .catch(function (err) { // API call failed...
        callback("I'm sorry, something went wrong when trying to get streamers. " + err);
    });
}
```

---

<div class="post-metadata">

**Author:** ![Alca](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/alca/32/2783_2.png) [@Alca](https://discuss.dev.twitch.com/u/Alca)\
**Post date:** [July 13, 2017, 5:03pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/10 "2017-07-13T17:03:50Z")

</div>

You could also `return` at `rp(options)` to return a Promise. You could still use the callback as well, just make sure to return the data in the `then` but throw in the catch if there’s no callback.

---

<div class="post-metadata">

**Author:** ![system](https://d2opxh93rbxzdn.cloudfront.net/original/2X/0/05909729875cce3b53e59d5561c4d23bb14948fc.png) [@system](https://discuss.dev.twitch.com/u/system)\
**Post date:** [August 12, 2017, 5:03pm UTC](https://discuss.dev.twitch.com/t/getting-response-with-nodejs-request-module/11020/11 "2017-08-12T17:03:55Z")

</div>

Closed on August 12, 2017, 5:03pm UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
