I'm having problems to redirect to another router after a Post. I see a 200 status code for the route I'm trying to navigate in the browser console and the whole page in the response payload. Through logs I see the redirect it's working, but the render is just not working.
I'm able to navigate to get to the page if I write the route manually in the browser, tho.
What am I missing?
I'll show you some code:
Server settings:
app.set('port', process.env.PORT || 9000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(require('./routes'));
app.use(express.static(path.join(basedir, 'public')));
Routes file:
router.get('/', (req, res) => {
res.render('login');
});
router.post('/login', (req, res) => {
res.redirect('/index');
})
router.get('/index', (req, res) => {
res.render('main-page');
})
PD: Yes...I'm totally new in Node.
From what you say, it sounds like you are sending an AJAX request. This means the response is delivered to your JavaScript code, it's not a navigation. So, essentially the redirect "works", as it redirects your AJAX request and returns the redirected page content.
If you were to submit a form via the browser (just using a basic <form> element), you would see a navigation.
In order for a navigation to occur after an AJAX request, you should not use res.redirect but instead return some JSON with the page you want to redirect to (e.g. res.send({ redirectTo: '/index' }) - the naming is your choice), and then check for the redirectTo parameter in your client-side code when it gets the response and navigate there manually using location.assign.
Example:
Server code:
router.post('/login', (req, res) => {
res.send({ redirectTo: '/index' })
})
Client code:
const result = await fetch('/login', { method: 'POST' })
const { redirectTo } = await result.json()
if (redirectTo) {
location.assign(redirectTo)
}
Alternatively, if the redirection target is static, you don't need any redirectTo value and can instead hardcode the target in the client-side code.
In case you want to allow both a form submit or an AJAX request (maybe you do progressive enhancement and your page is designed to work without JavaScript as well), then you can check the Accept header and see if HTML is accepted (req.accepts("html")), and if it is, you return a redirect, otherwise you return JSON. Similarly, in case of an error, you could conditionally render an error page or return JSON with an error message that your client-side code knows how to handle.
Related
I am working on this single page app where I send the App.html file to the user after login and then I want to fill that file with the data from the database.
I cannot find a way to simply do 2 get requests at the same time since one is for the file the other is for the data.
any work arounds ? as I have been reading you cannot send 2 requests for the same URL.
and since serving the file is eliminating my response window how can I implement this then?.
I want to stay on the same page so different route will not work because it's going to redirect me somewhere else and I will lose my access to the App.html that is already in the browser.
I also read that there is an option parameter in send file but it hasn't been working for me.
// Express Code
//Controler File
exports.getApp = async(req, res, next) => {
//app
res.sendFile(await path.join(__dirname, '../', 'views', 'App.html'))
}
exports.getData = async (req, res, next) => {
//data
const getData = await DB.find()
res.json(getData)
}
// Routes File
app.route('/app')
.get(toAppControler.getApp)
.get(toAppControler.getData)
Good morning all. I am trying to pass data to a view which is loaded in express via a redirect:
res.redirect('/manage-account/2-0/returns/answers')
The above is an html view which loads fine with just the redirect, but I want to pass some data. I can't pass data as part of a redirect, as far as I understand only a redirect?
So I have set up a GET for that route, and am trying to render the view with the data, but I am getting the error:
template not found: /manage-account/2-0/returns/answers.html
This is the route I created and how the page is initially redirected to in another view:
router.get('/manage-account/2-0/returns/questions', function (req, res) {
// stuff
res.redirect('/manage-account/2-0/returns/answers')
})
router.get('/manage-account/2-0/returns/answers', function (req, res) {
res.render('/manage-account/2-0/returns/answers', { data })
})
I found the possible way to write.
Server Side app.engine('html', require('ejs').renderFile); -
app.get('/main', function(req, res) {
var name = 'hello';
res.render(__dirname + "/views/layouts/main.html", {name:name});
});
Client side (main.html) -
<h1><%= name %></h1>
I'm trying to redirect to the home page after a user hit this route: /ref=123 but I want to keep that baseUrl, this is what I have so far:
I am requiring in my server.js file this: const referred = require('./routes/referred').
app.use('/ref=:id', (req, res, next) => {
res.locals = req.params.id
}, referred)
So, when a user hits the above route I am doing some validations in my referred.js file. Actually I need to send some kind of response telling whether that provided id exist or not but showing anyways the home page which is a simple login/resgistration form.
referred.get('/', (req, res, next) => {
//doing validations with res.locals
next() //<- calling the next middleware
})
after calling next() I put that middleware just below to redirect to the home page.
not sure if this is possible: app.use(express.static(_dirname + '/dist')) it seems like is not because I'm getting a 404 .
I know I could use the req.redirect() function but that will actually made a new request to the server and refresh the page erasing the baseUrl that I want to keep up there.
How do you render/send your pages?
You could use res.sendFile('path/to/page.html') to send back any html file while keeping the request URL.
If you want to display a dynamic message on the home page, you should use a viewing engine like ejs. If you are already using an engine, you can do something like
res.render('path/to/page', { status: 'This id does not exist!'})
I'm using Node and Express for the first time to make a simple website that conducts CRUD operations on a database. When I issue my put request I can't get the page to redirect to '/index' and I've run debugger for express and haven't seen anything abnormal, the page simply doesn't change. Any thoughts? Here's the code in server.js
app.set('view engine', 'ejs')
app.all('/', function(req,res){
var cursor = db.collection('jobs').find().toArray(function(err, results) {
res.render('index.ejs', {jobs: results})
})
})
app.get('/index',function (req, res) {
res.sendFile(__dirname + '/index.html');
})
app.get('/view',function (req, res) {
var cursor = db.collection('jobs').find().toArray(function(err, results) {
res.render('index.ejs', {jobs: results})
})
})
app.post('/jobs', function(req, res) {
db.collection('jobs').save(req.body,function(err, result){
if (err) return console.log(err)
console.log('saved to database');
res.redirect('/view');
})
})
app.put('/view', function(req, res) {
res.redirect(303, '/index');
})
An HTTP redirect just tells the client to get the data it asked for from somewhere else. It doesn't tell it to treat it any differently.
If you make an Ajax request and get a redirect response, then the browser will follow that redirect silently and return the contents of the new URL to your JavaScript.
The browser won't see the redirect and decide to load a new page in the viewport instead of presenting the data to your JavaScript.
If you want to load a new page after making your PUT request, then you need to wait for the response to come in and then (for example) assign a new value to window.location.href.
On the front page of my app, the user can register an account and then login. It is expressed as a login and register button on the front page which then show the appropriate form when either are clicked.
I would like to replace the two buttons with a log out button if the user is already logged in but I need to inform the client of that first.
In my index.js, I am serving static html like so
app.use(express.static('public'));
I thought I could then do the following
app.get('/', function(req, res) {
// inform the client if req.user isn't null
});
but the callback is never called
I have found a solution.
In my index.js, I have this
app.get('/isloggedin', function(req, res) {
res.json({ loggedin: (req.user != null) });
});
And then I can just send a get request for /isloggedin and handle the result
$.get('/isloggedin', {}, function(data) {
if (!data.loggedin) {
// remove logged-in only elements
} else {
// remove logged-out only elements
}
});
Umm! i guess there would be a login/register form so there has to be two routes one with .get() and second one with .post():
app.get('/', function(req, res) {
// This is for navigation to the home page
}).post('/', function(req, res){
// inform the client here about the req.body.user
});
and i guess you have set up this:
app.use(bodyParser.urlencoded({extended:true})); // for "formurlencoded"
app.use(bodyParser.json()); // for "application/json"
if not then you have to load this module require('body-parser') first and require it only if you are using express 4.