Here’s a more flexible way to do calls in the future, sticking to fairly vanilla code. It’s made to work similar to the “request” Node.js module.
var clientID = 'Client ID here';
// Base for making requests
function request(opts, callback) {
var req = new XMLHttpRequest();
var url = opts.url;
// Prepended URL part
if('baseUrl' in opts && opts.baseUrl) {
url = opts.baseUrl + url;
}
var qs = (opts.qs || {});
var qsKeys = Object.keys(qs);
// Add query string
if(qsKeys.length) {
var querystring = qsKeys
.map(function(key) {
return [ key, qs[key] ]
.map(function(n) { return encodeURIComponent(n); })
.join('=');
})
.join('&');
url += '?' + querystring;
}
var method = opts.method || 'get';
req.open(method, url, true);
var headers = opts.headers || {};
var headersKeys = Object.keys(headers);
// Add headers
if(headersKeys.length) {
headersKeys.forEach(function(key) {
req.setRequestHeader(key, headers[key]);
});
}
if(callback) {
req.addEventListener('load', function() {
let data = this.responseText;
// Try to parse the JSON if asked for
if(opts.json) {
try {
data = JSON.parse(this.responseText);
} catch(err) {
callback(err, this);
return;
}
}
callback(null, data);
});
req.addEventListener('error', function(err) {
callback(err, this); // Not quite sure how XMLHTTPRequest errors work
});
}
req.send();
return req;
}
function kraken(opts, callback) {
// Assign default Twitch Kraken API base
if('baseUrl' in opts === false) {
opts.baseUrl = 'https://api.twitch.tv/kraken/';
}
// Assign default headers
opts.headers = Object.assign({
Accept: 'application/vnd.twitchtv.v5+json',
'Client-ID': clientID,
}, opts.headers || {});
// Use JSON
opts.json = true;
return request(opts, callback);
}
So how can you use this? Create specific-use functions to make calls simple and clear in the rest of the code.
Key | Type | Description
--------+---------+--------------------------------------------------------
url | string | The URL, or partial URL to request
--------+---------+--------------------------------------------------------
baseUrl | string | A part of the URL to be prepended to url
--------+---------+--------------------------------------------------------
qs | object | A key/value representation of the request's querystring
--------+---------+--------------------------------------------------------
headers | object | A key/value representation of the request's headers
--------+---------+--------------------------------------------------------
json | boolean | Whether or not to attempt to parse as JSON
--------+---------+--------------------------------------------------------
Use kraken
like a default-option base function and pass just the new parts.
// Get the user object
function usernameToUserObject(username, callback) {
return kraken({
url: 'users',
qs: { login: username }
}, function(err, data) {
if(err) {
callback(err, data);
}
else if(data.users.length > 0) {
callback(err, data.users[0]);
}
else {
callback(err, null);
}
});
}
// Get just the "_id" key
function usernameToID(username, callback) {
return usernameToUserObject(username, function(err, data) {
if(err) {
callback(err, data);
}
else if(data !== null) {
callback(err, data._id);
}
});
}
In action:
// Will print "7676884" to the console
var req = usernameToID('alca', function(err, data) {
if(err !== null) {
console.log(err);
return;
}
console.log(data);
});