With Node.js, how can I make two HTTP GET requests and combine the resulting data and send it back to a user? - node.js

Say I have the following code that sends back json data (that I get from example.com first) back to a user that made a post request
app.post('/riot', function(request, response) {
var riotAPI = https.get("https://example.com", function(riotResponse){
var body = "";
riotResponse.on('data', function(chunk){
body+= chunk;
});
riotResponse.on('end', function(){
response.type('json');
response.end(body);
});
});
});
What do I do if I want to get more data from a different website and send json data from both website back to user? I am using express.

There are a number of ways you can do this. I would suggest using the request npm module instead of calling https directly. With request you can simply pass in callback which is called when a request finishes, so no need to deal with chunks of data.
If you take this approach then you can just use something like async.parallel() to run both requests in parallel. async.parallel takes one callback that is called when all of its async functions have finished.. and that is where you would send your response.

Related

http.request vs http.createServer

What is the difference between the request in this line of code:
http.createServer(function(request,response){. . .}
and request in
http.request()
Are both requests done to the server?
I am new to node.js and I am sorry if I sound dumb!
How does http.request() work?
In http.request() we fetch data from another site but in order to fetch data from another site we first need to go to our site and then make a request? Explain it with a simple real-life example!
http.request() makes a request to another HTTP server. Suppose for some reason I wanted to go download Stack Overflow's home page...
http.request('https://stackoverflow.com/', (res) => {
// ...
});
http.createServer()... it creates an HTTP server. That is, it binds your application to a socket to listen on. When a new connection is made from somewhere or something else, it handles the underlying HTTP protocol of that request and asks your application to deal with it by way of a callback. From the Node.js documentation:
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('okay');
});
These two methods have absolutely nothing to do with each other. http.request() is for making a request to an HTTP server. http.createServer() is for creating your own HTTP server. Don't get confused by the callbacks.
Based on the source code of nodejs (extract below), createServer is just a helper method to instantiate a Server.
Extract from line 1674 of http.js.
exports.Server = Server;
exports.createServer = function(requestListener) {
return new Server(requestListener);
};
The http.request() API is for when you want your server code to act as a client and request content from another site and has GET, POST, PUT, DELETE methods.

How can I send information from NodeJS server to client side?

For example, I want to signal to the client side that a username sent via the POST method in an HTML form already exists in my database.
I know how to recuperate POST data with body-parser and I know how to look it up in a MySQL database.
I know that I could use Ajax to write an error message directly on the form. What does my NodeJS server need to send and how does it send this information?
I've searched through numerous tutorials and I just found solutions where they send a new HTML page. I want to keep my web page the same and use functions like appendChild() to post the error message.
There are a couple of ways you could send data from server-side, so NodeJS, to client-side - which I assume in your case would be some JavaScript file like main.js that handles DOM manimulation.
So, the 1st way you could send data is through a templating engine like Handlebars, for example. There is an easy to use module for express you could get here: hbs.
Now to quickly summarize how an engine like that works, we are basically sending an HTML file like you probably saw in the tutorials, however, a templating engine like Handlebars allows us to send actual data with that file dynamically, so what we would do is render a specific Handlebars template (which in core is just HTML), and pass in a JavaScript object to the render call which would contain all the data you want to pass into that file and then access it in the .hbs file.
So on the server-side, we would write something like this, assuming we have a file called home.hbs and set up Handlebars as the templating engine:
router.get('/home', function(req,res) {
var dataToSendObj = {'title': 'Your Website Title', 'message': 'Hello'};
res.render('home',dataToSendObj);
});
And access in home.hbs like this:
<html>
<header>
{{title}}
</header>
<body>
message from server: {{message}}
</body>
</html>
Now, the issue with this approach is that if you wanted to update the data on the page dynamically, without having to reload the page, using a templating engine would not be ideal. Instead, like you said, you would use AJAX.
So, the 2nd way you could send data from your NodeJS server to the front-end of your website, is using an asynchronous AJAX call.
First, add a route to whatever route handler you are using for AJAX to make a call to. This where you have some logic to perhaps access the database, make some checks and return some useful information back to client.
router.get('/path/for/ajax/call', function(req,res) {
// make some calls to database, fetch some data, information, check state, etc...
var dataToSendToClient = {'message': 'error message from server'};
// convert whatever we want to send (preferably should be an object) to JSON
var JSONdata = JSON.stringify(dataToSendToClient);
res.send(JSONdata);
});
Assuming you have some file such as main.js, create an AJAX request with callbacks to listen to certain event responses like this:
var req = new XMLHttpRequest();
var url = '/path/for/ajax/call';
req.open('GET',url,true); // set this to POST if you would like
req.addEventListener('load',onLoad);
req.addEventListener('error',onError);
req.send();
function onLoad() {
var response = this.responseText;
var parsedResponse = JSON.parse(response);
// access your data newly received data here and update your DOM with appendChild(), findElementById(), etc...
var messageToDisplay = parsedResponse['message'];
// append child (with text value of messageToDisplay for instance) here or do some more stuff
}
function onError() {
// handle error here, print message perhaps
console.log('error receiving async AJAX call');
}
To summarize the above approach using AJAX, this would be the flow of the interaction:
Action is triggered on client-side (like button pressed)
The event handler for that creates a new AJAX request, sets up the callback so it knows what to do when the response comes back from the server, and sends the request
The GET or POST request sent is caught by our route handler on the server
Server side logic is executed to get data from database, state, etc...
The new data is fetched, placed into a JSON object, and sent back by the server
The client AJAX's event listener for either load or error catches the response and executes the callback
In the case of a successful response load, we parse the response, and update the client-side UI
Hope this is helpful!

POST Request creates file, followed by GET Request to download

Trying to do something seemingly basic.
I'd like to create a POST request through which I'll be sending JSONs. These JSONs will be created into files, which I'd like to return to the user via download.
The use case for this is that I'm building an application which takes a form and converts it into a JSON for upload to a MongoDB database. Users can load these JSONs into the application to re-load their old records as templates.
This is how I'm approaching it as of now:
// Download JSON Previews
var jsondownload = {};
// Grabs the JSON from POST request
app.post('/api/download', function(req, res, next){
jsondownload = {};
var json = req.body;
jsondownload = json;
res.json(jsondownload);
next();
});
// Immediately downloads the JSON thereafter
app.get('/api/download', function(req, res){
res.set({"Content-Disposition":"attachment; filename='test.json'"});
res.send(jsondownload);
});
What's the right way to do this?
There is no one "right" way to do it, but a few solutions include:
Remove the GET route handler (and the jsondownload variable) completely and just respond immediately with the Content-Disposition set appropriately. This is the better of the 3 because it reduces code and keeps things simple.
Use a simple redirect in your POST route handler. Instead of responding with the JSON immediately, you would do res.redirect('/api/download').
Do more or less what currently doing, but move the logic (the res.set() and res.send()) to a separate function that gets called from both route handlers.

Context IO node.js client library

I'm using Context.io's Node.js client library to get the body of emails from my account which is done in my code below.
Once I have that data, I am confused as to how I would get them over to the front-end. I'm new to the whole MEAN stack, and from my research of the basics, I have gathered that with Node, you can make the http calls, parse the json response and then write it to the server, but it seems as if I would have to make an API to then be able to call it from Angular and display it how I wish. I know that with other back-end languages like PHP, you can just write the code within the html, and not need a middle structure to get the info from PHP to the front-end. Is there an easier way than writing my own API in Node after having already made an API request to Context.io?
ctxioClient.accounts(ID).messages().get({limit:10}, function ( err, response) {
if(err) throw err;
console.log("getting responses...");
var messages = response.body;
console.log("message id is " );
console.log(messages.body);
You should implement the backend in JSON using something like res.json and make AJAX requests via Angular $http or something similar.

Pass additional arguments to node.js callack

I have created a rest client to make calls outside of my application. I want to send the data I receive back from the rest calls to the client's web browser.
Something like the following, but what is the best way to structure the code to allow access to the response to write back to the web browser with as loose coupling as possible? I don't want to define the rest client within a request handler.
var servReq = http.request(options, function(restResponse){
var status = restResponse.statusCode
var headers = restResponse.headers
restResponse.setEncoding("utf8");
d='';
restResponse.on('data', function(chunk){
d += chunk;
})
restResponse.on('end', function(restResponse){
// res would be a response to write back to the client's web browser
// with the data received from the rest client.
res.writeHead(200, {"content-type":"text/plain"})
res.write(d)
res.end();
})
}
Using request, you can pipe the API response straight to your application's response. This way it'll be completely loosely coupled—your server will return precisely what the API returns.
request(options).pipe(res);
https://github.com/mikeal/request#streaming

Resources