Node.js - Download file after asynchronous functions are done - node.js

I have got a reverse proxy and a node.js server which sends a plain/text response back to the proxy which, in turn, does a bunch of front-end stuff 0% related to my problem.
The plain/text response comes from multiple asynchronous functions and the user is informed of the progress as each async function completes through the usage of
res.write("Example");
The problem is, the node.js server is supposed to prompt the browser for a download after all the async functions are complete. It's irrelevant how or where the file is downloaded.
I have tried to set the headers to Content-Disposition: attachment, but Node just throws something like Error: Can't set headers after they are sent.
Here's a code example:
app.post('/', function(req, res) {
res.statusCode = 200;
/*
Bunch of async functions
*/
res.download("some_file"); // This is included in the callback after all async functions are done
});
app.listen(3000, function() {
console.log('The server is running at http://whatever:3000/');
});
The async functions make use of eachSeries from the async module. This is another example of what I'm trying to accomplish:
async.eachSeries(func1,func2,function(err){
// something to prompt the user for download
});
Do I have to create another instance of express just to serve the download or is there some way to do everything within one express() instance?

Related

Socket.io and request and response objects

I'm quite new on node.js and now I'm learning socket.io.
I'm developing an app step by step so, at this time, I have an app that can login an user, do crud operation in mysql and mongodb and upload files, all these operations are manage with some web pages with HTML and javascript technologies launched directly from restify.
After that I'm tring to add socket functionality to, at this time, simple print who is online.
So, before I have something like:
server.get('/login', function(req, res, next){ ... });
and now I have something like:
socket.on("login", function (req, res, next){ ... });
but, naturally, req and res are undefined!
Are there the same objects into socket.io?
To my understanding, you want to pass values back and forth in your request and response using socket.io.
Yes it is possible to do that and you syntax should be something like this...
Using express.js:
io.on('login', function(req){
client.emit('response event', { some: 'data' });
Note: when using emit you send the data to everyone, you have other methods like .broadcast(), .to(), etc.. for other use cases refer to socket.io github for better understanding
And lastly, inside emit you define the function you want to call on the client side and the data you want to send to the client.

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

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.

How To Set Up A Ping Route (HEAD) For New Relic In Restify/Express

I need to monitor my application's uptime via New Relic. I'm using the Restify framework which is largely based on Express.
New Relic wants to make HEAD requests to my application, but I'm not sure how to set up a HEAD route correctly to satisfy New Relic. Currently, my Restify app returns a 405 error for "Method Not Allowed", which causes New Relic to have fits and send me non-stop emails about how my application is down, and I can't find any documentation from New Relic that shows how to set up a simple ping URL to satisfy them.
Is there anything I need to do other than this:
server.head('/ping', function(error, req, res) {
res.send("hello");
});
EDIT:
The parameters are mislabeled so the res.send() is actually trying to call next().send() which would be undefined. Removing the error parameter and shifting everything over fixed the code as discovered by the OP.
As per the restify documentation, you need to call return next() in your callback function:
http://mcavage.me/node-restify/#Routing
server.head('/ping', function (req, res) {
res.send('hello');
});
If you would like to respond immediately and not continue down the chain, you can pass false as a parameter in your call to next()

relation between front-end functions and server routes in node.js

Inexperienced with nodejs style programming, I'm looking at an open-source node.js app that has routes with the same paths in both the front-end main.js file and the routes.js file, as you see below. I'm assuming that when the function in main.js file gets called it triggers the route in routes.js, however, I can't figure out what if anything is getting passed from main.js to routes.js as a callback.
main.js
$.get('/ip', function (data) {
fp.val(fingerprint);
userId.val(md5(fingerprint + data.ip));
});
routes.js
app.get('/ip', function (req, res) {
res.json({
ip: req.connection.remoteAddress
});
});
There's nothing node-specific about the frontend script, it's just using jQuery.get to get the document at a given URL.
On the server-side, it looks like the app is using Express (or something like it) which modifies the .send() method of the response to allow sending arbitrary objects. When you send and object, Express JSON encodes it (using JSON.stringify(object) and sets the Content-Type header of the response to application/json. This content-type header is what tells jQuery to automatically parse the JSON response back into an object in the browser.
So there is no callback being passed from main.js to routes.js, it's just a bog-standard web request that sends JSON data back to the client.

Express api res.jsonp returns double callback

I have an Express server running at port 8080 with this route
app.get('/api', function (req, res) {
res.jsonp('user API is running');
});
I open a browser window to
http://ec2-54-226-27-72.compute-1.amazonaws.com:8080/api?callback=hello
The response in the browser is
hello && hello("user API is running");
Why are there 2 hellos? Is this a proper JSONP response from Express and will it be processed correctly by a client?
Yes, that's the proper format. The purpose of the first hello is to make sure that the function hello exists on the client before trying to call it (an error would occur if the function did not exist).
There's a little bit of info about this in the preview chapter of the express book here. I just read it the other day.

Resources