How to Fetch data from webAPi using nodeJS libraries? - javascript

I am new to nodeJS, i want to fetch data from webApi using nodeJS, for instance, when i make a call to the
mydomain/getAllStudents
i want all the students data and when i do
mydomain/student/4
then i want only the data of the student with the ID=2
-challenge-
using express i can specify the route like this
var app=express();
app.get('/getAllStudents',(request,response)=>{
console.log('we are listening !!!');
}).listen(8080);
but when i try to make a call inside the callback function, i not able to get the value, my complete code
var http=require('http');
var express=require('express');
var app=express();
var options={host: '172.17.144.6',
port: 8394,
path: '/api/Masterdata/getAllStudents',
method: 'GET'}
app.get('/getAllStudents',(request,response)=>{
http.get(options,(res)=>{
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
console.log('we are listening !!!');
}).listen(8080);
what i am trying to achieve is, when i hit mydomain/getAllStudents i want to get all the data. how can i do this with nodeJS? can i do this with nodeJS statisfying my requirement?

So basically you want to expose the data through express after parsing them from another API.
You can do like this:
To make the call from node js you can use this library:
node-rest-client
var Client = require('node-rest-client').Client;
var remoteURL = "172.17.144.6:8394/api/Masterdata/getAllStudents";
var express = require('express');
var students = express.Router();
students.route('/getAllStudents')
.get(function(req, res) {
client.get(remoteURL, function (data, response) {
console.log(data);
if(response.statusCode === 200)
res.status(200).send(data);
});
});

Related

node.js: The POST method in my RESTAPI does not work

I start learning Node.js and Express.js and I'm trying to create a simple API to list data from JSON file (using the GET method) and add a new user using the POST method.
the GET method works fine but the POST method does not work
when I request http://127.0.0.1:8080/listusers the API sends all users in a JSON file.
when I request http://127.0.0.1:8080/adduser the API has to add new User Info and send the new data back to the browser.
NOTE: I read all the questions on Stackoverflow about this problem but
non of them help me so I have to ask again.
the problem is when I request http://127.0.0.1:8080/adduser I get the following error
Cannot GET /adduser
here is the server.js:
var express = require('express');
var app = express();
var fs = require('fs');
var user = {
"user4" : {
"name" : "mounir",
"password" : "password4",
"profession" : "teacher",
"id": 4
}
};
app.post('/adduser', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
res.end(JSON.stringify(data) );
});
});
app.get('/listusers', function (req, res) {
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
console.log(data);
res.end(data);
});
});
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log("listening at http://%s:%s", "0.0.0.0", port)
});
The answer is in the error. Cannot GET /adduser. Keyword GET! If you are making a post request, be sure you include the appropriate headers and that you are making a POST request, with a body, and not a GET request. For instance if you are using fetch:
const myInit = {
method: 'POST',
headers: myHeaders,
body: {
...
}
};
fetch("http://127.0.0.1:8080/adduser", myInit)
.then(res => {
...
});

Node proxy server modify response after query in database

I am troubling with nodejs proxy server modified(write) response.
I want to achieve auto login for one site via node proxy server and for that i have to query in database then i can modified response but it seems req ended before req.write and getting Error: write after end
Below is my implementation so far.
var express = require('express');
var proxy = require('http-proxy-middleware');
var options = {
target: 'http://example.com/', // target host
changeOrigin: true,
onProxyReq: function onProxyReq(proxyReq, req, res) {
var _write = res.write;
var body = "";
proxyReq.on('data', function(data) {
data = data.toString('utf-8');
body += data;
});
res.write = function (data) {
try{
//I have database query here instead of setTimeout
setTimeout(function(){
/* Modified response here and write */
_write.call(res, data); //can't write because req already end
},3000);
} catch (err) {
console.log('err',err);
}
}
}
}
// create the proxy (without context)
var exampleProxy = proxy(options);
// mount `exampleProxy` in web server
var app = express();
app.use('/', exampleProxy);
app.listen(8080);
Can anyone guide me how to achieve this ?

io.sockets.emit works but io.sockets.on doesn't

I have to use Socket.IO with ExpressJS route. I am able to emit an event to client but unable to listen to event emitted from client. This issue comes in case when I have to use socket with Express route.
My server.js looks like this: (here emit command works but io.sockets.on doesn't). I have checked issues with similar problems but still didn't get any clear answer.
var express = require('express');
var app = express();
var server = app.listen(3000);
var io = socketio(server);
app.set('socketio', io);
app.post('/deploy', function(request, response) {
var io = request.app.get('socketio');
var dapp = "some data";
io.sockets.emit('deploy', dapp);
io.sockets.on('deploy_result', (result) => {
console.log(result);
});
})
io.sockets.on (or io.on) won't let you listen to all events, it's just for "connection" event. You'll have to attach your listener to each socket in order to listen to all events, like this:
io.on('connection', function (socket) {
socket.on('deploy_result', (result) => {
console.log(result)
})
})
Also it seems like you're trying to get an "acknowledgement" for an emit, in which case there already exists a better way - the acknowledgement callback, simply pass a callback method as an additional argument (after the data):
server.js
io.on('connection', function (socket) {
socket.emit('deploy', {some: 'data'}, function acknowledgement_callback (result) {
console.log(result)
})
})
client.js
socket.on('deploy', (data, acknowledgement_callback) => {
// Do something with `data`
// Then call the callback with any result:
acknowledgement_callback('result')
// This will fire the "acknowledgement_callback" above on server-side
})
You will need to install express and socket.io eg. in the directory where you have your files as you can see in your codes and then reference those links appropriately
I have updated your code so issue of express and socket will work. its now left for you to ensure that your application run as you like.
here is the link on how to install express
https://www.npmjs.com/package/express
var socket = require( './socket.io' );
var express=require('./express');
var app=express();
var server = require('http').createServer(app);
var io = socket.listen( server );
var port = process.env.PORT || 3000;
app.post('/deploy', function(request, response) {
var io = request.app.get('socketio');
var dapp="some data";
io.sockets.emit('deploy',dapp);
io.sockets.on('deploy_result', (result)=>{
console.log(result);
});
})

How to get more than one independent response data in Express js app.get callback

What is the best practice to send two independed MongoDB results in Express application via HTTP Method?
Here is a short example which makes it clear:
//app.js
var express = require('express');
var app = express();
var testController = require('./controllers/test');
app.get('/test', testController.getCounts);
...
Following getCounts() function wouldn't work because I can't send the response twice.
///controllers/test
exports.getCounts = function(req,res) {
Object1.count({},function(err,count){
res.send({count:count});
});
Object2.count({},function(err,count){
res.send({count:count});
});
};
Anyway, I would like to have those two counts in one response object.
Should I call Object2.count in the callback of Object1 even if they are not dependent to each other?
Or should I re-design it somehow else?
Thank you!
You should use Promise to achieve this task :
function getCount(obj) {
return new Promise(function (resolve, reject) {
obj.count({}, function(err,count) {
if(err) reject();
else resolve(count);
});
});
}
With Promise.all you can trigger the two request and retrieve the results in order to add it to the response
exports.getCounts = function(req,res) {
Promise.all([getCount(Object1), getCount(Object2)])
.then(function success(result) {
res.send({'count1':result[0], 'count2':result[1]});
});
});
When you call res.send you will end the response for the request. You could instead use res.write, which will send a chunk to the client, and when done call res.end;
Example:
app.get('/endpoint', function(req, res) {
res.write('Hello');
res.write('World');
res.end();
});
However, it seems like you are trying to send json back to the client which raises and problem: writing to object separately will not be valid json.
Example:
app.get('/endpoint', function(req, res) {
res.write({foo:'bar'});
res.write({hello:'world'});
res.end();
});
The response body will now be: {foo:'bar'}{hello:'world'} which is not valid json.
There will also be a race condition between the two db queries, which means that you are not certain about the order of the data in the response.
Suggestion:
exports.getCounts = function(req,res) {
var output = {};
Object1.count({},function(err,count){
output.count1 = count;
Object2.count({},function(err,count){
output.count2 = count;
res.send(output);
});
});
};
//Response body
{
count1: [value],
count2: [value]
}

Node JS OR Express JS HTTP GET Request

I am using express.js and I need to make a call to HTTP GET request ,to fetch JSON data .Please suggest me some good node js/express js modules/lib to perform get/post request .
Node.js provides an extremely simple API for this functionality in the form of http.request.
var http = require('http');
//The url we want is: 'www.random.com/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.com',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
console.log(str);
});
}
http.request(options, callback).end();
Here I attach some more examples with POST and custom headers. If you don't need special things, I'd stick to the native code.
Besides, Request, Superagent or Requestify are pretty good libraries to use.
var express = require('express');
var app = express();
var fs = require('fs');
app.get('/', function (req, res) {
fs.readFile('./test.json', 'utf8', function (err, data) {
if (err) {
res.send({error: err});
}
res.send(data);
})
});
var server = app.listen(3001, function () {
console.log('Example app listening port 3001');
});

Categories

Resources