Making ajax call to node server - javascript

I am new to NodeJS and trying to use npm spotcrime package to get crime data from user input location on click of a button through ajax call. Here is the usage of the package given on npm documentation page of package.
var spotcrime = require('spotcrime');
// somewhere near phoenix, az
var loc = {
lat: 33.39657,
lon: -112.03422
};
var radius = 0.01; // this is miles
spotcrime.getCrimes(loc, radius, function(err, crimes){
});
which works perfectly fine when run separately and returns correct crime json data. However I don't understand how to call this through ajax call on click of button. Any insights would be really helpful. Thanks in advance :)
UPDATE
Here is my server code
var express = require('express');
var app = express();
var dataFile = require('./data/data.json');
var reload = require('reload');
var path = require('path');
app.set('port', process.env.PORT || 3000);
app.set('appData', dataFile);
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(express.static(path.join(__dirname, '/public')));
app.use(require('./routes/index'));
app.use(require('./routes/information'));
app.use(require('./routes/spotcrime'));
var server = app.listen(app.get('port'), function(){
console.log('Go to http://localhost:' + app.get('port')+ ' on your
browser');
});
reload(app);
And here is spotcrime.js file
var express = require('express');
var router = express.Router();
var spotcrime = require('spotcrime');
router.get('/spotcrime', function(request, response){
var loc = {
lat: 33.39657,
lon: -112.03422
};
var radius = 0.01; // this is miles
spotcrime.getCrimes(loc, radius, function(err, crimes){
response.send(crimes);
});
});
module.exports = router;
I am trying this from quite a while but nothing shows up. Please suggest any way out

use this code to make ajax call
var http = require('http');
var request = require('request');
request.post({
url: "xxxxxxxxxxxx",
method: "POST",
json: true, // <--Very important!!!
body: {}
},
function(error, response, body) {
if (!error) {
console.log(body.d);
} else {
console.log(error);
}
}
);

If I understood correctly you want to send an AJAX request from a browser(front-end) to your server. This can easily be done with jQuery AJAX see the official documentation page. Here is an example for you:
<buttom class="send-request">Send AJAX request</button>
$(".send-request").click(function() {
$.ajax({
method: "GET", // since you are waiting for GET request on server
url: "/spotcrime", // you might have to provide full path to your endpoint starting with https://127.0.0.1/spotcrime
data: { Greetings: "Hello" } // data object can be deleted since you don't expect any parameters on server side
})
.done(function( msg ) {
alert( "Response data: " + msg );
});
});

Related

In Node.js, how to update different components of a page in different frequency?

I'm trying to build a real time webpage to show some real time statistics. This webpage has 12 components. I'm using Ajax in SetTimeout to update each component. Since I'd like to update each component in different frequency, I write a setTimeout function for each component and gives each component a link (defined in "main.js"). Looks like:
(function poll() {
setTimeout(function() {
$.ajax({
url: url1,
type: 'GET',
success : function(info){
var object = document.getElementById("1");
object.textContent = info;
}, complete: poll });
}, 5000);
})();
...
...
(function poll() {
setTimeout(function() {
$.ajax({
url: url12,
type: 'GET',
success : function(info){
var object = document.getElementById("12");
object.textContent = info;
}, complete: poll });
}, 10000);
})();
And in my "server.js", I hope to connect to database only once and then render different components. The configuration of the database will rely on the link so I organize the app like this:
app.get('/:A/:B', function(req,res){
var A= req.params.A;
var B = req.params.B;
var config = something relies on A and B
var client = new pg.Client(config);
client.connect(function(err){
if (err) {
console.log("Error occurred when try to connect the database",err);
}
else {
res.sendFile(__dirname + '/public/main.html');
app.get('/main.js', function(req,res){
res.sendFile(__dirname + '/public/main.js');
});
app.get('/url1',function(req,res) {
//query database and send the data url1 needs
});
...
...
app.get('/url12',function(req,res) {
//query database and send the data url12 needs
});
})
I want to ask if writing "app.get()" within "app.get()" like the code above is good practice. If not, how can I keep a global connection to the database and use it for different components? Also, is there any improvement I can make to this web app? I'm quite new to Node.js
If I had to do this with callbacks instead of promises, this is how I would do it on Server side.
first, I would use your endpoint to get the client, but would put it in a module internal variable, and still send a response if I failed to connect to DB.
var db=null;
app.get('/:A/:B', function(req,res){
var A= req.params.A;
var B = req.params.B;
var config = something relies on A and B
var client = new pg.Client(config);
client.connect(function(err){
if (err) {
console.log("Error occurred when try to connect the database",err);
res.status(503).send("Error connecting to database);
}
else {
db = client;
res.sendFile(__dirname + '/public/main.html');
}
}
}
Then, I would write a function that would reuse that DB if it exists:
function usingDatabase(req,res,next){
if(db) {
req.db=db;
next();
}
else {
res.status(400).send("Bad request. open the DB first by calling /:A/:B");
}
}
finally I'd use it like this:
app.get('/main.js', function(req,res){
res.sendFile(__dirname + '/public/main.js');
});
app.get('/url1',usingDatabase, function(req,res) {
// db is in req.db;
//query database and send the data url1 needs
});
...
...
app.get('/url12',usingDatabase,function(req,res) {
// db is in req.db;
//query database and send the data url12 needs
});

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

Callin a function in nodejs

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.

Socket.IO always emits to last connected client

I have a problem with Socket.IO (Node.JS).
I try to emit something to a client that makes a request, but Socket.IO answers to the latest connected client.
For example: I connect with my computer to the site, and connect with my laptop after that. Now I make a request with my computer, but my laptop is getting the answer.
My code looks like this:
Server:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server, { log: false });
var socket = socket;
io.sockets.on('connection', function (socket_) {
socket = socket_;
socket.on('dl_me', function (result) {
downloadTrack(result, result.song_uri);
if (typeof callback == 'function' ) {
callback({
success: success
});
}
});
});
var downloadTrack = function(result, uri) {
socket.emit('gotodownload', {
id: generated_number
});
}
Client:
var socket = io.connect( window.location.href );
socket.on('gotodownload', function(result) {
var linktodl = window.location.host + '/getme/' + result.id;
document.getElementById('dlbutton').innerHTML = 'Download!'
});
It's not the complete code, but every relevant socket.io part.
Try passing the socket object to your downloadTrack function:
// Add an argument for the socket object.
var downloadTrack = function(socket, result, uri) {
socket.emit('gotodownload', {
id: generated_number
});
}
And modify the code inside dl_me event to call the function like:
socket.on('dl_me', function (result) {
// Pass the socket to the function.
downloadTrack(socket, result, result.song_uri);
// ...
});

retrieve page source using node js

I have to do retrieve the page source of a page with nodejs, but the page that I want to retrieve isn't always the same.
I have 2 files server.js that is listening and when he receive A connections he call load.js that retrive the sourse of a non defined page, my code is this:
server.js
var net = require('net');
var loadFb = require('./load.js');
var HOST = 'localhost';
var PORT = 9051;
// Create a server instance, and chain the listen function to it
// The function passed to net.createServer() becomes the event handler for the 'connection' event
// The sock object the callback function receives UNIQUE for each connection
net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('User request profile of: ' + data);
// Write the data back to the socket, the client will receive it as data from the server
//here I have to call test.js
//how
sock.write(data);
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
the other file is this:
var https = require('https');
var options = {
host: 'graph.facebook.com',
port: 443,
path: '/dario.vettore',
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
//console.log(pageData);
return pageData;
});
res.on('end', function(){
//response.send(pageData)
});
});
How can I ask from the first file (server.js) to the second file to retrive for it the page source from the second file, But the page that I want to get the source can change isn't always the same..
In your second file (I'm assuming that's the one named loadFb.js), you want to export a function, instead of calling the code right away.
Node caches its modules so when you require() them, the code only gets run once.
The second file should look something like this:
var https = require('https');
module.exports = function(path, callback) {
var options = {
host: 'graph.facebook.com',
port: 443,
path: path,
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
});
res.on('end', function(){
callback(pageData);
});
});
};
Then in your first file, you would access it like this:
loadJs('/dario.vettore', function(pageData) {
console.log(pageData);
});
This way you can execute the module code many times, with different paths.

Categories