Callin a function in nodejs - javascript

I am looking to get data from steam api. This is what my server.js looks like.
I get the steamID from the req.query thing. Then I want them passed to the function as the last part of the url string.
So far I've tested the following: forced the key directly into the var url and removed the function. It worked.
I tried to create a var rekt after the req.query, and passed it like getData(rekt). It didn't work.
So I think calling of the function doesn't work because there is a different syntax for this in node js(as I'm new in it.) Hopefully it's enough information.
var request = require('request');
var express = require('express');
var app = express();
var gotSteamID;
app.use(express.static('site'));
app.get('/data.html', function(req, res){
gotSteamID = req.query.SteamID;
getData(gotSteamID);
});
function getData(gotSteamID) {
app.get('/steam/stats', function(httpRequest, httpResponse) {
var url = 'http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=730&key=IREMOVEDTHEKEY&steamid=' + gotSteamID;
request.get(url, function(error, steamHttpResponse, steamHttpBody) {
httpResponse.setHeader('Content-Type', 'application/json');
httpResponse.send(steamHttpBody);
});
});
}
var port = 4000;
var server = app.listen(port);
and the html post looks like
<form class="form" action="data.html" method="GET">
<input type="text" name="SteamID" placeholder="76561198101455802" id="steamIDvalue" name="selectpicker" required>
<input type="submit" name="submit" value="&#10140" onclick="getValue()" id="rekt">
</form>

Instead of the 2 app.get (one inside the function), why don't you expose 1 API call that gets the ID in the parameter?
app.get('/steam/stats/:id', function(httpRequest, httpResponse) {
var url = 'http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=730&key=IREMOVEDTHEKEY&steamid=' + id;
request.get(url, function(error, steamHttpResponse, steamHttpBody) {
httpResponse.json(steamHttpBody);
});
});
Then in the html, you need to call /steam/stats/id instead of /data.html?SteamId=xxx

Ultimately, it looks like you're attempting to setup another endpoint (via app.get()) in your request handler for /data.html. With that removed, your request.get() will now be invoked.
Using query params
The following should allow you to make GET requests to /data. I removed the .html since you're actually serving JSON from this endpoint (you'll want to change this in your form)
var request = require('request');
var express = require('express');
var app = express();
app.use(express.static('site'));
var appid = 730;
var key = 'IREMOVEDTHEKEY';
var api = 'http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/';
app.get('/data', function(req, res){
var steamId = req.query.SteamID;
var url = api + '?appid='+ appid +'&key='+ key +'&steamid=' + steamId;
request.get(url, function(error, response, body) {
res.setHeader('Content-Type', 'application/json');
res.send(body);
});
});
app.listen(4000);
Using URL params
If you'd like to move away from using a query param, you could use something like the following:
app.get('/steam/stats/:steamId', function(req, res){
var steamId = req.params.steamId;
var url = api + '?appid='+ appid +'&key='+ key +'&steamid=' + steamId;
request.get(url, function(error, response, body) {
res.setHeader('Content-Type', 'application/json');
res.send(body);
});
});
Cleaning up your Request
String concatenation is nice, but request offers a more convenient (and easier to read/maintain) way to create your API URL.
qs - object containing querystring values to be appended to the uri
If you broke out your appid and key as I did above, you can pass them to qs without having to worry about ? and & URL management.
request.get({
url: api,
qs: {
appid: appid,
key: key,
steamid: req.params.steamId
}
});
Just a friendly tidbit to help tidy up your code and save you from some potential frustration down the road.

Related

Get request from client to Node server with objects

How do I send an object from the client to the Node server.
My Object looks like this:
var myobj = {};
myobj.title = "title1";
myobj.message = "message1";
I simply want to send it to the server to save it to the database with mongoDB. But when I try to send it and look at the request, only unreadable text comes out.
This is the code on the client:
$.get( '/createA',myobj, function(data) {
console.log(JSON.parse(data));
});
This is my server code:
router.get('/createA', function(req, res, next) {
let gelp = req._parsedOriginalUrl.query;
let res1 = gelp.replace(/%22/g, "'");
var test = JSON.parse(res1);
});
I tried to format the string with the .replace() function and parse it back to JSON but it doesn't work.
Is there any other way I can get an object from client side JavaScript to Node and work with that object there?
see: https://api.jquery.com/jquery.post/
also just console.log or do res.send('it worked!') to test these things out for the first time instead of trying to modify things before you know the backend is receiving it.
$.post("/createA", myobj, function( data ) {
console.log( data.title );
console.log( data.message );
}, "json");
and try this first.
router.post('/createA', function(req, res) {
res.send('it worked!')
});
after that works, you can try to modify and send back the object. like so
router.post('/createA', function(req, res) {
var data = {}
data.title = req.body.title.toUpperCase()
data.message = req.body.message.toUpperCase()
res.send(data)
});

How to display image from http request to external API with Node.js

I have a situation where in order to get images for a site that I am building, I need to make a http request to an external server for information. Currently, the responses from the requests come in two forms, XML and images. I am doing this using Node.js.
For the XML, I'm able to parse it without issues and it can be passed into a variable and handled like everything else. With the images, I'm stuck, I have no idea how to get them "displayed" on the page after making the request for them. The farthest I have been able to get is to correctly set the request up in postman. My question is, can I pull the image from the body of the response of the request that I'm making to another server and get it to display in the web app that I'm building?
I'm very new to the back end world and am trying to learn as I go. This is an example of what I have been able to do find and use for parsing an XML response that I get from the API
var request = require("request");
var express = require("express");
var jsxml = require("node-jsxml");
var app = express();
var fs = require("fs");
app.get('/users', function(req,res) {
console.log("List of users requested.");
// We will grab the list of users from the specified site, but first we have to grab the site id
// (Same idea as when we added users. We could have checked if req.session.SiteID has been populated,
// but I chose to keep it simple instead)
request(
{
url: 'http://' + SERVERURL + '/api/2.0/sites/' + SITE + '?key=name',
headers: {
'Content-Type': 'text/xml',
'X-Tableau-Auth': req.session.authToken
}
},
function(err, response, body) {
if(err) {
req.session.err = err;
res.redirect('/');
} else {
var bodyXML = new jsxml.XML(body);
console.log("site id: " + siteID);
}
// OK. We have the site, now let's grab the list of users
// Since we're just making a GET request, we don't need to build the xml. All the is needed
// is the SiteID which is inserted in the url and the auth token which is included in the headers
request(
{
url: 'http://' + SERVERURL + '/api/2.0/sites/' + siteID + '/users/',
headers: {
'Content-Type': 'text/xml',
'X-Tableau-Auth': authToken
}
},
function(err, response, body) {
if(err) {
req.session.err = err;
} else {
// A succesful request returns xml with a <users> which contains multiple <user> elements.
// The <user> elements have name attributes and id attributes which we'll grab, store in a
// javascript object and render those in the html that loads.
var bodyXML = new jsxml.XML(body);
bodyXML.descendants('user').each(function(item, index) {
userIDs[item.attribute('name').getValue()] = item.attribute('id').getValue();
});
for(var user in userIDs) {
console.log(user + " " + userIDs[user]);
}
}
res.render("users.ejs", {
err: req.session.err,
userIDs: userIDs,
site: SITE
});
}
);
}
);
});
Any help would be hugely appreciated. Thanks!
Step 1: Fetch image and save it on node server. request module documentation on streaming for more options
request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'));
Step 2: send the saved image as response.
app.get('/display', function(req, res)) {
fs.readFile('doodle.png', function(err, data) {
if (err) throw err; // Fail if the file can't be read.
else {
res.writeHead(200, {'Content-Type': 'image/jpeg'});
res.end(data); // Send the file data to the browser.
}
});
};

Get Google Maps Geocoding JSON from Express

I've been teaching myself Node.js and Express, and I am trying to return the JSON result from a Google Maps Geocoding API request. I have gotten it to to work using the require module, BUT I am trying to figure out what I did wrong in Express so I have learned it:
Express Attempt: htmlController.js
// FYI: This controller gets called from an app.js file where express() and
// the mapsAPI is passed as arguments.
var urlencodedParser = bodyParser.urlencoded({extended: false});
module.exports = function(app, mapsAPI){
app.post('/maps', urlencodedParser, function(req,results){
var lat;
var long;
var add = req.body.add;
app.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + add + '&key=' + mapsAPI, function(req,res){
lat = res.results.geometry.northeast.lat;
long = res.results.geometry.northeast.long;
console.log(lat); // no output
console.log(lat); // no output
}, function(){
console.log(lat); // no output
console.log(long); // no output
});
results.send("Thanks!");
});
}
As you can see, I am trying to log it in different code blocks, but any log inside the API request is not getting shown to the console.
Working Request using the require Module:
app.post('/maps', urlencodedParser, function(req,results){
var add = req.body.add;
request({
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=' + add + '&key=' + mapsAPI,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body) // Print the json response
}
});
results.send("Thanks!");
});
If I understand you correctly, you are trying to get data from maps api by using app.get()
app.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + add + '&key=' + mapsAPI, function(req,res){}
But app.get() function is used for your app route only, not to fetch remote data. same for router.get()
// app.get(appRoute, middlewareORhandler)
app.get('/myOwnApp/api/users/12/', function(res,res,next)){
// your code here
res.status(200).send("return your response here");
}
to make a remote request you can use built-in httpmodule. request and superagent are great and easy to make remote requests
to install those module:
npm install request --save
var request = require('request');
npm install superagent --save
var request = require('superagent');
see more at : https://www.npmjs.com/package/request

Angular with hapi js server jsonp

I have an endpoint defined at /api/profile which accepts post parameters.
var http = require('http');
var serverConfig = require('../server.config.js');
var request = require('request');
module.exports = function(server){
server.route({
method: 'POST',
path: '/api/profile',
handler: getProfileData
});
function getProfileData(request, reply){
var battleTag = request.payload.battleTag;
getProfileDataHttp(battleTag, function(err, data){
if(err){
reply(new Error(err));
}
reply(data);
});
}
function getProfileDataHttp(battleTag, callback){
var key = serverConfig.battleNet.apiKey;
var tag = encodeURIComponent(battleTag);
var url = 'https://eu.api.battle.net/d3/profile/'+ tag + '/?locale=en_GB&callback=JSON_CALLBACK&apikey=' + key;
console.log(url);
request(url,function(error, response, body){
if(error){
callback(err);
}
if(!error && response.statusCode ==200){
callback(null, body);
}
});
}
};
it is calling an api with a json callback, when I am receiving the data it is in format:
JSON_CALLBACK({ json data here})
how can I get this endpoint to return just the json data, I have tried JSON.parse() but it causes errors in the server.
the angular service that calls this endpoint is like below:
function getProfileData(battleTag){
var defer = $q.defer();
var tag = validTag(battleTag);
if(!tag){
defer.reject('Invalid Tag please use format 1[a-z]11[a-z0-9]#4[0-9]');
return defer.promise;
}
$http.post('/api/profile', {
battleTag: battleTag
})
.success(function(data){
if(data.reason){
defer.resolve(data.reason);
}
defer.resolve(data);
})
.error(function(err){
defer.reject(err);
});
return defer.promise;
}
the call would work when using $http.jsonp in angular however I had to create the server to hide the secret key from the client
Your question is a bit confusing. You are talking about JSONP, but you want to fetch the data directly.
The whole point of JSONP is to return the data encapsulated inside a function that you choose. You then simply have to execute it.
If you want the data in a direct way, don't use JSONP. Simply do a "normal" call.
After having a quick look at the Battle.net API, it seems that to get the data directly, you should simply omit the 'callback' parameter in the URL of your request.
Thus, your request URL would looks like that:
var url = 'https://eu.api.battle.net/d3/profile/'+ tag + '/?locale=en_GB&apikey=' + key;

How do I know which request belongs to what partial data in node.js

I have the node.js server below. Suppose that multiple clients make a POST request. But these will share the same variable body and the final string will become meaningless. Is is possible to identify a request by id or something? All I have is request.headers, but that does not contain any unique information.
var http = require("http");
var server = http.createServer();
server.on("request", onRequest);
server.listen(8001, "127.0.0.1");
function onRequest(request, response) // assuming "POST"
{
var body = "";
request.on("data", function (data) { body = body + data; });
request.on("end", function () { console.log(body); });
}
Functions in general inherit scopes (from their parents), so each body variable will be correctly concatenated for each request.

Categories