Unable to do post request on node.js server using express - javascript

I have an index.js file which has code to handle get and post requests.
GET request is working pretty fine, the problem is with POST.
here is my code.
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.post('/', function(req, res, next) {
console.log("post request to index");
res.render('index', { title: 'Express' });
});
module.exports = router;
Using Rest client, if I ping my server with a method, i am getting 400 error.
Please help.
Nikhil

Related

Express route only works after the second try

I am using the express framework for a node.js backend server. I am using the express router to define the different routes.
This is my app.js file:
var express = require('express');
var app = express();
var server = require('http').Server(app);
var cors = require('cors');
app.use(cors());
app.use(express.json());
var route = require('./route');
app.use('/api/', route);
server.listen(3000, () => {
console.log('App running on port 3000!');
});
This is my router route.js:
var express = require('express');
var router = express.Router();
var controller = require('./controller');
router.use(function (req, res, next) {
next();
router.get('/test', function (req, res, next) {
controller.get(req, res, next);
});
});
module.exports = router;
The route itself uses a controller for the logic controller.js
exports.get = function (req, res, next) {
res.send('Hello World');
}
Starting the app with node app.js and calling the defined route http://localhost:3000/api/test will result in a Cannot GET /api/test on the first try. Calling the route a second time however will result in the expected answer hello world.
What is the reason for the first call failing? Why does it work on the second try? Any ideas are appreciated
Because router.use(function (req, res, next) { will only get executed on the first request, and when you call next() the route was not yet added. Afterwards you call router.get(...) which will add the route, so it will be available the next time.
Nevertheless thats just bad, move the .get(...) outside of .use(...) (you can also get rid of it entirely).

How do I reroute a GET request from my root in app.js to a route in my controllers folder in Express.js?

I'm basically trying to recreate this from Sinatra in Express:
get '/' do
redirect '/channels'
end
I'm trying to build a Node.js/Express.js app and am starting to incorporate an MVC structure. My app.js file contains my / route, as such:
app.js
app.get('/', function(req, res) {
res.redirect('/search');
})
I want it to redirect to the /search route in controllers/search.js, which contains the following:
controllers/search.js
const express = require('express');
const app = express();
app.get('/search', function(req, res) {
res.render('index.js');
})
The browser does redirect to localhost:3000/search but it displays Cannot GET /search. All of the tutorials and documentation I see about rerouting in Express don't show the whole file so I'm not able to tell if I have to require or export anything ala Node.js.
Any help is appreciated.
try this
server.js
var http = require('http');
var express = require('express');
var searchRouter = require('./searchRouter');
var app = express();
app.use('/', searchRouter);
var server = http.createServer(app);
server.listen(3000);
searchRouter.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('Nope, try /search');
});
router.get('/search', function(req, res, next) {
res.send('yeah!! you found me');
});
module.exports = router;
you can extend this logic by
app.use('/search', searchRouter);
in search router
// this handles /search
router.get('/', function(req, res, next) {}
//this handles /search/apple
router.get('/:id', function(req, res, next) {}

Router.use requires middleware function?

So I'm trying to seperate my login routes in a seperate JS file called login_routes.js
I keep getting this specific error:
TypeError: Router.use() requires middleware function but got a Object
at Function. (/Users/ethanthomas/Desktop/mean-stuff/express-server/node_modules/express/lib/router/index.js:446:13)
Not entirely understanding what it's asking me to implement?
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
server.js:
var express = require('express');
var app = express();
var path = require('path');
var adminRoutes = require('./app/routes/admin_routes');
var loginRoutes = require('./app/routes/login_routes');
app.use('/admin', adminRoutes);
app.use('/login', loginRoutes);
//send our index.html file to the user for the home page
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
//start the server
app.listen(1337);
console.log('leet is the magic port');
Your login_routes.js should look something like this (in the context of express):
var express = require('express');
var router = express.Router();
// GET request to /login
router.get('/', function(req, res, next) {
// do something
});
// POST request to /login
router.post('/', function(req, res, next) {
// do something
});
module.exports = router;
In your app.js you use
var login_routes = require('./login_routes');
...
app.use('/login', login_routes);
...
Have a look at the code generated by the express-generator module. That is a starting point for express webserver apps.
People have already offered hints at the solution in comments.
The first issue is that you need to export your "sub" app from login_routes.js. To do so, change this:
var app = express();
Into this:
var app = module.exports = express();
Secondly, you are—probably unintentionally—creating routes for GET /login/login and POST /login/login. To solve this, use this in login_routes.js:
app.route('/').get(...).post(...);
This is because the root path in your sub app (the one in login_routes.js) will get mapped to the path used in app.use() in your main app (server.js).
Do like this:
login_routes.js:
exports.get = function( req, res ) {
res.send('this is the login form');
};
exports.post = function( req, res ) {
console.log('processing');
res.send('proccessing the login form!');
};
server.js:
var loginRoutes = require('./app/routes/login_routes');
app.get('/login', loginRoutes.get);
app.put('/login', loginRoutes.post);
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
module.exports = router;
just writ module.exports = router then it will be work

Creating a MVC-restful application upon express

I'm trying create my own application based on rails (not equal, but similar).
So, i'm creating this basic stuff to send to github, so i can use in any project, and i have a problem with my routes.
I am using the express-resource to create the cruds routes.
This is my app.
Controller/example.js:
exports.index = function(req, res, next){
res.send('forum index');
next();
};
exports.new = function(req, res, next){
res.send('new forum');
next();
};
exports.create = function(req, res, next){
res.send('create forum');
next();
};
exports.show = function(req, res, next){
res.send('show forum');
next();
};
exports.edit = function(req, res, next){
res.send('edit forum');
next();
};
exports.update = function(req, res, next){
res.send('update forum');
next();
};
exports.destroy = function(req, res, next){
res.send('destroy forum');
next();
};
exports.load = function(id, fn){
process.nextTick(function(){
fn(null, { title: 'Ferrets' });
});
};
Them in my routes.js:
var express = require('express');
var resource = require('express-resource');
var client = express();
routes.resource('example', require('../controllers/example'));
module.exports = routes;
and my app.js:
// Routes
var routes = require('./routes/routes.js');
app.use('/', routes);
Now the problem:
I can access only the index and the new routes. When i try access:
http://localhost:3000/example - will show right, but with a 304 http code.
http://localhost:3000/example/new - will show right, but with a 304 http code.
http://localhost:3000/example/create - will show the /show/ and a 304 http code.
http://localhost:3000/example/show - will show the /show/ and a 304 http code.
http://localhost:3000/example/edit - will show the /show/ and a 304 http code.
http://localhost:3000/example/update - will show the /show/ and a 304 http code.
http://localhost:3000/example/destroy - will show the /show/ and a 304 http code.
In the terminal, the following error occur:
GET /example/edit 304 1.080 ms - -
Error: Can't set headers after they are sent.
I'm stuck in this.. i dont know the problem. Please, somebody help! haha
Thanks Very Much!
res.send('forum index');
next();
either respond or pass the request along for other middleware to respond, not both.
Replace:
function(req, res, next)
with
function(req, res)
And remove next();
next don't stop a request.
res.send('final output'); // end output
Try:
exports.index = function(req, res){
res.send('forum index');
};
exports.new = function(req, res){
res.send('new forum');
};
exports.create = function(req, res){
res.send('create forum');
};
exports.show = function(req, res){
res.send('show forum');
};
exports.edit = function(req, res){
res.send('edit forum');
};
exports.update = function(req, res){
res.send('update forum');
};
exports.destroy = function(req, res){
res.send('destroy forum');
};
exports.load = function(id, fn){
process.nextTick(function(){
fn(null, { title: 'Ferrets' });
});
};
This is other alternative: https://www.npmjs.com/package/express-enrouten
Check this article (spanish) http://blog.mcnallydevelopers.com/cargar-controladores-de-forma-automatica-en-expressjs-con-node-js/
Rails clone? http://sailsjs.org/
You don't have to call next() while you already called send() the middleware that called by next() trying to call send but couldn't because already sent as the .send() doesn't return and your process keep executing, just remove next()

Get POST request when using Router middleware

I'm using Passport to authenticate my users on NodeJS. Currently I'm using ExpressJS and I'm trying to route my traffic. I currently use the following code:
website.js (main file)
require("./routes.js")(app);
routes.js
var pages = {
home: require("./pages/home"),
about: require("./pages/about"),
register: require("./pages/register"),
login: require("./pages/login"),
api: require("./api/index")
};
module.exports = function(app) {
app.use("/", pages['home']);
for (page in pages) {
app.use("/" + page, pages[page]);
}
app.get("/logout", function(req, res) {
req.logout();
req.redirect("/");
});
}
register.js
var express = require('express');
var router = express.Router();
var app = express();
router.get("/", function(req, res) {
res.render("register", { page: "Register", message: req.flash("registerMessage") });
});
app.post("/", passport.authenticate("register", {
successRedirect: "/about/",
failureRedirect: "/register/",
failureFlash: true,
successFlash: "Logged in!"
}));
module.exports = router;
The problem I am facing is that POST requests to this will result in a 404. The page is not found. The GET request (so /register) properly shows the registration form, but upon submitting I get a 404. If I change router.get("/", function(req,res){}) to router.use("/", function(req, res, next) {}), I will get HTTP 500 errors when I call "Next()" (Can't set headers after they are sent.), and POST still doesn't work.
Could anyone tell me how to correctly catch POST requests behind router middleware?
I solved my issue
I solved my issue by using the following:
router.route("/")
.get(function(req, res, next) {
res.render("register", { page: "Register", message: req.flash("registerMessage") });
})
.post(passport.authenticate("register", {
successRedirect: "/about/",
failureRedirect: "/register/",
failureFlash: true,
successFlash: "Logged in!"
}));

Categories

Resources