ExpressJS is stacking up - node.js

Im trying to make an API that works through the power of the framework nodejs and the node module/package express
I made an API that once you call localhost:3000/?username=nameHere
It makes some http requests using the request module, waits for the callback and then sends the result out as html to the person requesting localhost:3000/?username=nameHere
However if I refresh it quickly, the ending result would be a stack of 2 results instead of one
Example: localhost:3000/?username=nameHere would return 1 array
if i quickly call/refresh it 2 times, the route acts the same for everyone and the ending result would stack up 2 arrays
How do I overcome this? I'm seriously new to routing.
Here's my code, app is simply express() and i Did define some variables at the top, GetAllItems basically is a function that does a bunch of requests made by the the request module, wraps up all the data and sends it back as a callback
app.use('/', function(req, res,next) {
console.log("request");
if (req.query.username!==undefined) {
GetID(req.query.username,function(ID){
if(ID!==undefined || ID!=="undefined"){
console.log("Cool");
GetAllItems(ID,function(cb){
res.send(JSON.stringify(cb));
next();
});
}else{
console.log("Not found");
res.send("Not Found");
}
})
}else{
res.send("No username");
}});

Related

How to set Routes for APIs

I am building an API to manage meetups with nodeJS. I have build an endpoint with the route "/meetups/:id/" to fetch a specific meetup record by its id. And then I want to fetch all the upcoming meetup records and I tried to use "/meetups/upcoming/" but when I query it, I get the not found error (404). It seems like the second route is not recognised.
Here is the code defining the two routes
the request from postman
Any help on how can I handle that?
Thanks.
Route is '/api/v1/meetups/upcoming/all'. Move res.status outside the map function.
EDIT: you'll have to change the route which has to be different from api/v1/meetups/:id. Reason is when route '/api/v1/meetups/upcoming' is requested express sees it as the same route as before and takes 'upcoming' as the parameter.
app.get("/api/v1/meetups/upcoming/all", function(req, res) {
var today = new Date();
var upcomings = db.meetups.map(function(meetup) {
if(meetup.happeningOn > today) {
return meetup;
}
});
res.status(200).send({
status: 200,
data: upcomings
});
});
You need to move the res.status piece outside of the const upcomings definition.

Node.JS run routes synchronously

In this example, I have two routes - the first is a Get route and the second is a Post route. I want the information gathered in the get route to be included in the post route. I tried using .then and some basic boolean if logic but I cannot get these routes to run synchronously.
leadFormObj = {};
$.get("/getID/"+leadFormObj.parentEmail, function(event){
console.log("getting an ID");
console.log(event[0].id);
leadFormObj.parentID = event[0].id;
});
console.log(leadFormObj);
$.post("/addChild", leadFormObj, function(data) {
console.log(leadFormObj);
console.log("sent");
});
In the example above, I have a standard object (i've shown it blank in this example). The first get route will run and pass in a new key value pair to the object. I then want to pass this updated object to the post route but I'm not sure how to do this.
Would I use nested routes to do this?
Thanks!
Why don't you put the post request inside the callback of the get request
$.get("/getID/"+leadFormObj.parentEmail, function(data){
$.post("/addChild", {parentID: data[0].id}, function(data) {
console.log("sent");
});
});

Handling request simltaneously in nodejs and passing it's response using only one res.send

I am developing an API which takes input in XML containing IDs for media and gives output in XMLform with details of given IDs. I am facing a problem while sending the response of second simultaneous request; here the second request goes into loop showing "loading" on postman.
What I am doing is calling a function in app.post which parses the media and gives output in the callback and send it using res.send, but it works only for single request.
While doing parallel request to same API either it goes in loop or it gives can't set the headers after they are sent as I am using res.send but res.send is the only way which I can use to send the response (even the next doesn't work).
var getCompositeData = function(req, res, next){
abc.getData(req.body, function(err, xmlOutput){
if(err){
console.log("error");
} else {
xmlData = xmlOutput
return next()
}
}
app.post(apiUrl, [
rawBodyParser({
type: 'application/xml'
}),
app.oauth.authorise()
], getCompositeData, function (req, res) {
res.setHeader('Content-Type', 'application/xml');
res.send(xmlData);
});
There are several issues with your code:
if (err) {
console.log("error");
}
If an error occurs, you still need to make sure a response will be sent back, otherwise the request will stall until a timeout happens. You can pass an error to next, and Express will handle it:
if (err) {
return next(err);
}
Next problem:
xmlData = xmlOutput
xmlData is an undeclared variable, which gets overwritten with each request. If two requests happens at (almost) the same time, it's likely that one client gets back an incorrect response (remember, Node.js runs JS code in a single thread; there is not thread-local storage so xmlData gets shared between all requests).
A good place to "store" this sort of data is in res.locals:
res.locals.xmlData = xmlOutput;
return next();
// and later:
res.send(res.locals.xmlData);

node request pipe hanging after a few hours

I have an endpoint in a node app which is used to download images
var images = {
'car': 'http://someUrlToImage.jpg',
'boat': 'http://someUrlToImage.jpg',
'train': 'http://someUrlToImage.jpg'
}
app.get('/api/download/:id', function(req, res){
var id = req.params.id;
res.setHeader("content-disposition", "attachment; filename=image.jpg");
request.get(images[id]).pipe(res);
});
Now this code works fine, but after a few hours of the app running, the endpoint just hangs.
I am monitoring the memory usage of the app, which remains consistent, and any other endpoints which just return some JSON respond as normal so it is not as if the event loop is somehow being blocked. Is there a gotcha of some kind that I am missing when using the request module to pipe a response? Or is there a better solution to achieve this?
I am also using the Express module.
You should add an error listener on your request because errors are not passed in pipes. That way, if your request has an error, it will close the connection and you'll get the reason.
request
.get(...)
.on('error', function(err) {
console.log(err);
res.end();
})
.pipe(res)

How does the 'reverse path' in Node.js Connect work?

So I understand that Node.js Connect works like a stack through which it runs, starting from the top and going to the bottom. From the Connect introduction by its author at http://howtonode.org/connect-it it shows an example like
var Connect = require('connect');
module.exports = Connect.createServer(
require('./log-it')(),
require('./serve-js')()
);
The article reads
Every request enters the onion at the outside and traverses layer by
layer till it hits something that handles it and generates a response.
In Connect terms, these are called filters and providers. Once a layer
provides a response, the path happens in reverse.
I'm particulary curious about "Once a layer provides a response, the path happens in reverse". How does that happen? Every middleware gets called again, but in reverse order?
No, they don't get called again in reverse, but each middleware has a chance to monkey-patch the request methods and hijack them. It's not ideal.
// basic logger example
module.exports = function () {
return function logger(req, res, next) {
var writeHead = res.writeHead;
res.writeHead = function (code, headers) {
console.log(req.method, req.url, code);
res.writeHead = writeHead;
return res.writeHead(code, headers);
};
next();
};
};
Now, this code has issues because writeHead isn't the only way to set the status code, so it won't catch all requests. But that is the basic way that middleware can catch events on the way out.

Resources