Nodejs cannot Read and Write simultaneously - javascript

I am currently trying to develop a NodeJS application, which contains 3 main Routes:
app.get('/1',(req, res) => {
res.sendFile(path.join(__dirname, './index.html'))
});
app.post('/1',(req, res) => {
model.sharetime(req.body.zeit);
});
and
app.get('/receive', (req, res) => {
res.json(model.receivetime());
});
The post Route /1 will be called once ever second, which receives a value that is put into an array.
The problem that I encounter is, each time I want to call the route /receive while the /1 get route is open, there is no response whatsoever,
after I restart the server, suddenly I get the response that I requested.
Which basically means, I cant have the route /1 which opens my index file open which I need for the application to post results back to the server and simultaneously receive the updated values via the route /receive.
Please help :)

You're not responding to the request, you're merely calling a function with a value from the posted form. Add at least a res.end(); to that route handler.

Related

using stream.pipe make express middleware skipped

im using express and nodejs for my api server,
and now im implementing pdf download (im using pdf-creator-node) for converting html to pdf.
the pdf-creator-node will create a stream when converting a html, and when i pipe it, all my middleware (notFoundHandler, errorHandler,responseLogger) got skipped
router.get(
'/generatePDF', authenticate, schemaValidation({ params: generatePDFschema }),
(req, res, next) => {
generatePDF(details) {
const template = readFile('./src/templates/da-template.html');
const receipt = {
html: template,
data: payload,
type: 'stream'
};
const generatedPdf = pdf.create(receipt, advisOptions);
return generatedPdf;
}
const pdfStream = generatePDF(details);
res.setHeader('Content-type', 'application/pdf');
pdfStream.pipe(res);
},
notFoundHandler,
errorHandler,
responseLogger
);
is there any express api can i use to pipe a stream?
The middleware you show is passed to router.get() AFTER your request handler so it will not get a chance to run unless you call next() in your request handler. When you pass multiple request handlers to a router.get(), they will run sequentially in order and the 2nd one will only get a chance to run if the first one calls next(). Same for the 3rd one, and so on.
Furthermore, pdfStream.pipe(res); does not call next().
I don't know exactly what those middleware functions are supposed to do, but making a guess based on their names, perhaps they are supposed to run BEFORE your request handler, not after so they can put things in place for various error conditions.
If you want further help, then please show the code for those three middleware functions so we can see more specifically what they are trying to do.

Update global variables on website after post

In index.js I am rendering page with global variables.
router.get('/index', function(req, res, next) {
res.render('index', { title: 'RLH',
countNumber: countNumber,
countReleased: countReleased,
countOpen: countOpen
});
in the same index.js I also have:
router.post('/index', function(req, res, next) {
datatamper = req.body;
countSev();
countTickets();
countTime();
});
On port 3000 I am listening for data, once I get it I am making some calculation and then the page is ready to be opened with global variables.
Clearly this is working just fine to open the page and all data will be here
On the page I am presenting data like that:
<p> <b> Tickets</b>: <span>{{countNumber}}</span></p>
Yet I would like to update just the data on the website by itself after every post(not refreshing the whole page).
Data by post is coming every minute, yet that might change.
You need to implement either some form of longpolling, where your javascript frontend sends requests to the api every so often to check for updates, and then adds them to the page, or use a technology like websockets to get the data as it's updated.

Sending information to server and getting processed data back using nodejs

I'm trying to make an application using nodejs, express and ejs. What I'm aiming to do is submitting a form to the server, trigger a server function which processes the data to get some result, and getting my page to display the result without reloading the whole page.
Currently this is what I have:
ejs
<form method = "GET" action = "/sendinput"
...something here
</form>
app.js
app.get('/sendinput', function (req, res) {
result = processData(req.query);
});
I manage to get the function to run when the form is submitted, but after that the page keeps loading even after the function finishes running. I'm also not sure how to fetch the result and let the form segment of the html displays it without reloading the whole page.
To stop the page from loading, use res.end();
it will signal the server that your function is done.
app.get('/sendinput', function (req, res) {
result = processData(req.query);
res.end();
});
So in the end I solve it by using Ajax, which doesn't prompt the page for a reload and manage to get what I want.

Node.js preresponse with Express

So I'm doing a web page with Node.js and Express framework. I already have registration and login (I'm holding users id in a session). Next step is to render different page whenever a user is authenticated.
Some of those pages require a User object which is just a mapping of a user from my db. So whenever an authenticated request comes I need to retrieve the user from my db. But writing this code every time seems to be a bad way to do this. So here's the question: is it possible (and if it, then how?) to do, say preresponse, so I can automaticaly retrieve User object whenever I know that the user is authenticated and THEN do the main response?
Middleware is what you are referring to. Middleware is just a function that gets called sequentially when the route is triggered. So to have a loadUser function:
function loadUser(req, res, next) {
// You would fetch your user from the db
var user = users[req.params.id];
if (user) {
req.user = user;
next();
} else {
next(new Error('Failed to load user ' + req.params.id));
}
}
app.get('/user/:id', loadUser, function(req, res){
res.send('Viewing user ' + req.user.name);
});
You can define as many middleware functions as your need. Just be sure to call next() at the end to pass the route handling on to the next function.
This EXACT example is covered in the express.js route middleware docs. Go read it and you'll see the pattern of using middleware to factor out common functionality that you need at many route paths in your app.

Passing error message to template through redirect in Express/Node.js

In my Node.js application, I have a function (routed by Express) which presents a form to the user:
app.get('/register', function (req, res) {
res.render('form');
});
I have another function, routed to the same URL, but which handles POST requests, which receives the data submitted by the previous form. If the form does not validate, it redirects the user back to the form; otherwise, it does what should be done:
app.post('/register', function (req, res) {
if (validate(req.registerForm)) return res.redirect('back');
persistStuff(req.registerForm, function (err, data) {
// Do error verification etc.
res.redirect('back')
});
});
What I want to do is to send a error message to be presented, in the line:
if (validate(req.registerForm)) return res.redirect('back');
To write something like
if (validate(req.registerForm)) return res.render('form', {msg:'invalid'});
is unacceptable because I want to follow the POST-REDIRECT-GET pattern. I could do something like
if (validate(req.registerForm)) return res.redirect('/register?msg=invalid');
but it would hardcode an URL in my code and I'd prefer to avoid it. Is there another way to do it?
You need to use flash notifications, and it is built into express.
You'll add a message like so: req.flash("error", "Invalid form...");
You'll need a dynamic handler to add the messages to your rendered template, or you can check out the ones TJ has made for express. (express-messages)
You could simply have it redirect as res.redirect('..?error=1')
the ? tag tells the browser that it is a set of optional parameters and the .. is just a pathname relative recall (like calling cd .. on terminal to move back one directory)
and you're browser will direct to the appropriate page with that tag at the end: http://.....?error=1
then you can simply pull the error on the appropriate page by doing a:
if (req.param("error" == 1)) {
// do stuff bassed off that error match
};
you can hardcode in several different error values and have it respond appropriately depending on what error occurred

Categories

Resources