Nodejs page not redirecting after POST - javascript

My problem is similar enough to this but also different and the answers aren't working for me.
I have a form to post and I need to display a message on the page whether it entered the data to the database successfully or not. So I have:
app.post('/add_new', upload.single('image'), function add_new(req, res, err)
{
var image = req.body.image;
// do some checks and try to insert
if (err){
res.render('page_name',{images:images, message:'There was an error'})
}
else{
images.push(image);
res.render('page_name',{images:images, message: 'Success'})}
}
}
The error/success messages are handled on the client side.
My problem is that it doesn't actually complete the post. It renders the page with the error/success message correctly but the URL looks like 'my_site.com/add_new', and if the user refreshes the page for any reason, it sends that 'form resubmission' alert, which causes problems. I need it to go back to 'my_site.com' and display the message.
I have found that doing
res.redirect('back')
returns to the correct page but obviously doesn't display the message.
I have noticed a few answers recommending
res.end('Success')
but that just displays a white page with the word 'Success' - I don't know how anyone thinks that's an acceptable solution!
EDIT:
Following Vinay's answer, my code now reads like:
app.post('/add_new', upload.single('image'), function add_new(req, res, err)
{
var image = req.body.image;
// do some checks and try to insert
if (err){
req.session.msg='error adding';
res.redirect('page_name');
}
else{
images.push(image);
req.session.msg='success';
res.redirect('page_name');
}
}
and this to get the page:
app.get('/page_name', is_logged_in, function(req, res) {
if(req.session.msg){
res.render('page_name', {images: images, user:req.user, message: req.session.msg});
setTimeout(req.session.msg="", 4000);
}
else{
res.render('page_name', {images: images, user:req.user, message:''});
}
});
But I am still finding that the error message persists when the page is refreshed. Have I made a mistake?

currently you are doing this
if (err){
res.render('page_name',{images:images, message:'There was an error'})
}
else{
images.push(image);
res.render('page_name',{images:images, message: 'Success'})}
}
you are getting url like this to 'my_site.com/add_new', which is correct rendering means your are loading/rendering html page to particular route which is '/add_new'.
There may be a two solution
1st solution
res.redirect('/?msg=' + string);
and on home page
app.get('/', function(req, res){
if(req.query.msg){
// display error message
}else{
// else do not display error
}
});
2nd solution
req.session.msg = "message here";
res.redirect('/');
and on home page you can do like this.
if(req.session.msg){
//display error message here
// after displaying msg in that last this
setTimeout(req.session.msg="", 3000); // this will clear a session after 3 seconds, so next time it will not display the msg.
} else {
//or display home page without error.
};
you can use one of them.

Related

How to track visits or clicks on an Url shortener using ExpressJS and NodeJS?

I'm working on a URL shortener for learning purposes, and I want to add a way to track the clicks or visits for each shortened URL.
An example of a shortened URL from my app is this: http://localhost:3000/384oxt where the code 384oxt is saved in my database and is related to the URL: https://www.google.com/.
So, when the user visits: http://localhost:3000/384oxt, I have this method to do the redirect:
const redirect = async (req, res) => {
const { code } = req.params;
if (!code || !(await ShortenedUrl.existsUrlCode(code))) {
return res.status(404).json({
status: 'err',
errors: [
{
message: "The urlCode doesn't exist",
},
],
});
}
try {
const shortenedUrl = await ShortenedUrl.findOne({ urlCode: code }).exec();
console.log(req);
return res.redirect(301, shortenedUrl.source);
} catch (err) {
console.error(err);
return res.status(500).json({
status: 'err',
errors: [{ message: 'A problem has occurred, please try again' }],
});
}
};
As you can see, I get the code, then I check if the code exists in the database, if not, I return a response with the message error, but if the code exists, I get from the database the URL that is linked to that code and I do the redirect.
The first time, it works OK, and this instruction: console.log(req); prints the request on the console.
But if I use the same shortened URL again: http://localhost:3000/384oxt, it seems like the browser is doing the redirect without entering the redirect method in my NodeJS app. The instruction console.log(req); is not printed anymore. Even if I delete the method, the redirect still works.
I want to store some statistics like the browser, time, etc when someone uses the shortened URL, but with this behavior, I can't.
How can I force that every time the shortener URL is used the method is executed?

Redirect after form submit or not?

At the bottom of my personal page (1 page website) I have a contact form that sends a message to my database so I can read it later.
The problem is that if I don't redirect to anywhere, the page doesn't reload, which is what I want, but is searching for something and have a loading icon in the tab and eventually disconnects and show the "ECONNRESET" error from Cloud9.
If I do redirect back to /#contact (to the page and then down to the contact section), then it reloads the page, and that's not what I want to happen because of the site's functionality. It has some animations that load right after sending the message and the reload cancels them out and it looks terrible.
How do I make it so that the page doesn't have to reload after sending the message, meaning I don't have to redirect anywhere, but I also don't get the ECONNRESET error?
app.post("/", function (req, res){
// Retrieve form data
var name = req.body.name;
var email = req.body.email;
var subject = req.body.subject;
var message = req.body.message;
var newMessage = {name: name, email: email, subject: subject, message: message};
// Save new message to database
Message.create(newMessage, function (err, sendMessage) {
if (err) {
console.log(err);
} else {
console.log(sendMessage);
}
});
});
If you are not posting the form via AJAX, then you should redirect to the GET endpoint where your view is rendered. If you do not want to redirect, then at the very least you will need to have a res.render() call to render the correct view. The drawback to not redirecting is that if the user refreshes the page, they may get prompted to resubmit the form.
Message.create(newMessage, function(err, sendMessage){
if(err){
console.log(err);
} else {
console.log(sendMessage);
res.render('contact'); //change 'contact' to the name of the view you are rendering
}
});
I did some searching and I found a way to do it how I want it to work: no redirecting or reloading the page.
I removed the unnecessary error handling and console.log since all I need is for the form to send the data to my database so I can read it later.
app.post("/", function(req, res){
// Retrieve form data
var name = req.body.name;
var email = req.body.email;
var subject = req.body.subject;
var message = req.body.message;
var newMessage = {name: name, email: email, subject: subject, message: message};
// Save new message to database
Message.create(newMessage);
});
Apparently I need a Ajax/jQuery request, which looks like this:
$('form').submit(function(e){
e.preventDefault();
$.ajax({
url:'/',
type:'post',
data:$('form').serialize(),
success:function(){
//whatever you wanna do after the form is successfully submitted
}
});
});
Source to the answer I found (First answer)

How do I do a try/catch for my specific API Call example?

so my question is very specific. Whenever I run this bit from my page I get an error if I don't input the CORRECT ID I need to search for in the API. It doesn't know what to do when it doesn't make a valid API call because the query string is incorrect. How do I go about redirecting to a different page WHEN there's an error like that or how do I prevent it from STOPPING the program? I'm assuming there's a try catch in here but I tried it multiple different ways and I'm still confused because it doesn't work. Help please! I'm new to this... Here's the snippet. The request portion of the code is where the error occurs if the "bnetID" is not a valid ID. If it is valid it runs perfectly fine...
// Make a GET request to the /results page (When submit is pressed)
app.get("/results", function(req, res){
// Retrieve bnetID and REGION from the FORM
var bnetID = req.query.bnetID;
var region = req.query.region;
// Replace the # with a -
bnetID = bnetID.replace("#", "-");
// Create the query string
var url = "http://ow-api.herokuapp.com/profile/pc/"+ region +"/"+bnetID;
// Make the API request
request(url, function(err, response, body){
if(err){
console.log(err);
} else {
var playerData = JSON.parse(body);
playerData = findImportantData(bnetID, playerData);
checkIfExists(bnetID, playerData);
res.render("results", {data: playerData});
}
})
});
Why don't you handle what you want to do if there is an error?
if(err){
console.log(err); // change this to whatever you want to do
}

How to replace error message with an error page

I currently have when something goes wrong i display error text but i would like to replace this with a presentable error page instead of just text and wanted a little more help on how to go about this.
This is currently my code for displaying error text:
return function (req, res, next) {
errorRepo.get(req.get('error'), serviceTokenHandler.makeToken(), function (err, errorInfo) {
if (err || !errorInfo) {
res.status(500).render('error', {
message: 'This is my error message'
});
} else {
.....
next();
}
});
};
What do i need to do to redirect to an error page instead of just showing a message? Should i replace the inside of the if block with a method call that would redirect to another page?
I assume you are using express for your application. If you want to render a beautiful error page, you would do that just as you would render any other page.
The only difference between an error page and a "normal" page is - simply put - the http status code which ranges above 400.
E.g. you'd do:
...
if (err || !errorInfo) {
res.render('error-page', function(err, html) {
res.status(500).send(html);
});
}
...
Assuming you are using Express 4.x.
You can create an error.html file which you want to render when error occurs.
<html><body>
ERROR
</body> </html>
In node render the error.html when error occurs:
if(error) {
res.sendFile('error.html', { root: path.join(__dirname, '../views');
}
This way you can keep the html and node code seperate.
Express 4.x documentation for referance http://expressjs.com/en/4x/api.html#res.sendFile

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