router.get not posting multiple params - node.js

Hi so I am learning basics of node.js and express, and I was trying to submit a form with two parameters and trying to get that in the same screen.
But for some reason I guess I am not sure how to use router.get to get the both input fields parameters.
Here is my js file
var express = require('express');
var router = express.Router();
router.get('/:awesomeTitle?/:awesomeAuthor?', function(req, res, next) {
res.render('node',
{title: req.params.awesomeTitle ? req.params.awesomeTitle : '' , author: req.params.awesomeAuthor ? req.params.awesomeAuthor : '' });
});
router.post('/', function(req, res, next) {
var awesomeTitle = req.body.title;
var awesomeAuthor = req.body.author;
res.redirect('/' + awesomeTitle + awesomeAuthor);
});
module.exports = router;
And here is my hbs file.
<h1> Result </h1>
<h2>{{author}}</h2>
<h1>{{title}}</h1>
<form action="/" method="post">
<input type="text"/ name="title">
<input type="text"/ name="author">
<button type="submit">Submit</submit>
</form>
So just wanted to know how to get the awesome title and author from submit to the page again in the h1 and h2 tags.
P.S I am not sure how to debug this application so.. and it doesn't show any errors, all I get is both the input fields answer combined.

It looks like you're missing a / in your redirect. Try changing the last line in your post handler to this:
res.redirect('/' + awesomeTitle + '/' + awesomeAuthor);

Related

Cannot POST (node/express), what am I missing?

I'm trying to use a simple POST request with Node using Express and instead am getting cannot POST with a 404. In the end I want to use ajax so it POSTs without refreshing the page in the browser, but first I need to get it running like this and I can't figure out what I've gotten wrong.
public/form.html
<!DOCTYPE html>
<form method="POST" action="">
<input name="firstName">
<input name="lastName">
<input type="submit">
</form>
app.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
//server running?
app.listen(3000,() => {
console.log('Started on PORT 3000');
})
//Serve the web page directory
app.use(express.static('./public'))
//Return form fields
app.post('form.html', (req, res) => {
console.log("First name: " + req.body.firstName)
console.log("Last name: " + req.body.lastName)
res.end()
})
app.post("/api", (req, res) => {
console.log("First name: " + req.body.firstName);
console.log("Last name: " + req.body.lastName);
res.end();
});
Here you have to make POST request to /api
<form method="POST" action="/api">
I've figured it out and will share in case others are looking for the same thing. The other responses are correct, but I was looking to POST without changing the URL. This doesn't look to be possible because I always get cannot POST and a 404 if I point to the existing page (either leaving action empty or using "#").
However, when you use AJAX, you still point to a new URL with the form action attribute and in your node app, but your AJAX code will keep the URL on the same page (the page doesn't refresh).

node.js: Can I do a POST under a router like below?

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){
res.send("post works");
});
module.exports = router;
This is my index.js file.
I used express to create an app, add my own jade file which has a form in it.
Can i define a post method like that? I am new to node.js so dont really have a grasp on how this works?
I would like to add i am trying to save data to a mongodb instance.
Update: 26/11/18
I got the solution after i got the answers given down below,
I am adding the GitHub link.
I have added the working files to it.
Below is an example html login form, to make a post route work you have to make sure you define method="POST" and action="/(Insert Route)". In my example action="/login", this means that there would be a post request that is sent to /login. If I had a router setup that accepted all /login requests it would be redirected there and the router.post('/') would work.
<form action="/login" method="POST">
<p">Username</p>
<input type="text" name="username" placeholder="Enter Username">
<p>Password</p>
<input type="password" name="password" placeholder="Enter Password">
<input type="submit" name="" value="Login">
</form>
After searching the web for clarification at the end both the answers helped me out. I was trying to do a POST request from my route, i had the variable "router". What I overlooked was to add the function name to it. My html form was trying to submit to a function "/login" and My router did not have the function defined.
router.post('/login', function(req,res, next){
}
This did it.
Thanks to everyone that tried to help.

Cant get the data from form post to nodeJS server

I am trying to write a login page . i got the html page with the login box
im enter email and password than submit to server , on server i got route who get the data check on db if doc exists , if its exists should redirect to main page
the problem is the data i send from form to server always undefined i check here on other ppl questions and i didnt find any good result for this
html login page :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<title>{{PageTitle}}</title>
</head>
<body>
{{> header}}
<div class="login-box">
<div class="form">
<form action="/get_user" method="post" class="login-form">
<input type="email" name="Email" placeholder="Email"/>
<input type="password" name="Password" placeholder="Password"/>
<button type="submit">login</button>
</form>
</div>
</div>
{{> footer}}
</body>
server code :
const _ = require('lodash');
const express = require('express');
const bodyParser = require('body-parser');
const {mongoose} = require('./db/mongoose');
const hbs = require('hbs');
var {User} = require('./models/user');
var app = express();
app.set('view engine', 'hbs');
const port = process.env.PORT;
hbs.registerPartials(__dirname + '/../views/partials');
app.user(bodyParser.json());
app.use(express.static(__dirname + '/../public'));
app.use(express.static(__dirname + '/../public/images'));
app.use(express.static(__dirname + '/../public/fonts'));
app.listen(port, () => {
console.log(`Started on port ${port}`);
});
app.get('/', (req, res) => {
res.render('login.hbs', {
PageTitle: 'Log In',
ConnectUser: 'Guest'
});
});
app.post('/get_user', (req, res) => {
var body = _.pick(req.body, ['Email , 'Password']);
User.findOne({
Email: body.Email,
Password: body.Password
}).then((user) => {
console.log(body.Email + ' ' + body.Password);
if(!user) {
return res.status(404).send();
}
var fullName = user.First_Name + ' ' + user.Last_Name;
res.redirect('/mainPage', {ConnectUser: fullName});
}).catch((e) => {
res.status(400).send();
});
});
i did few checks and when i call /get_user req.body->var body -> user r empty
the data arnt pass from form to server im also check this route on postman and its work find when i write the body by myself the only problem i can think is the data i send from form arnt send as json and the body parser send only in json format so maybe i need to change the line
app.use(bodyParser.json());
if any 1 can put in the right direction ill appraise that ty.
When using an html form with method post, the data is posted to the server withContent-Type: application/x-www-form-urlencoded instead of JSON.
Json bodyparser will not do anything with that, as its not using JSON format to send the data. See MDN guide under post method.
In your server code, below app.use(bodyParser.json()) add the following:
app.use(bodyParser.urlencoded({extended: true}));
This will add the data onto the request body the way you expect.
Try playing with the form enc-type attribute and see how to configure the bodyparser to get the values you need based on the enc-type.
application/x-www-form-urlencoded
multipart/form-data
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype

Can monk return a json of data directly instead of a promise?

I learning express recently,and want to make a tiny blog with express+mongodb+monk+ejs,below is the code I writed:
model are some js exports function to handle data:
var db = require('../model/public').db;
var contentCollection = db.get('contentcollection');
exports.getContent = function (fn) {
contentCollection.find({},{},function(err,data){
fn(data);
});
};
controller is deal with route:
var express = require('express');
var router = express.Router();
var $data = require('../model/core').$content;
var $ = require('../controller/util');
router.get('/', function(req, res, next){
$data.getContent(function(data){
res.render('content', $.extend(req.staticRes, {
article: data
}));
});
});
module.exports = router;
(in this code,"$" is a util function include a method to extend double object just like jQuery.extend do.)
view is page that be controller render:
<% include ./public/head %>
<%include ./public/header%>
<%for(var i = 0;i<article.length;i++){%>
<div class="article">
<div class="title">
<%= article[i]["title"]%>
</div>
<div class="content">
<%= article[i]["content"]%>
</div>
</div>
<%}%>
<script src="/js/content.js"></script>
<% include ./public/footer %>
what confused me is the part of model,i only can access data in a method named
xxx.find({},{},function(data){
//some handle with data
})
that result in that i only use the getContnet function like that:
router.get('/', function(req, res, next){
$data.getContent(function(data){
res.render('content', $.extend(req.staticRes, {
article: data
}));
});
});
but i only want to handle the data query from database like below's form,so I can use some function that query data form different collection:
router.get('/', function(req, res, next){
res.render('content', {
article: $data.getContent('some arguments here to query from content collection'),
user: $data.getUser('some arguments here to query from user collection')
});
});
my vocabulary is poor,thanks to google translate ;-)
anyone help?
add:
var s = contentCollection.find({},{},function(err,data){
fn(data);
});
console.log(s);
is a Promise when i console it.
OK,I find the solution by myself.
After research my colleague'code whom project based on Koa,I find the different between my code with him:it's not the fault of monk which make me confuse that i mentioned above,it's the blame of Express!
below is Koa's code style for route to render page:
yield this.render('index', {
topics: $Topic.getTopicsByTab(tab, p),
items: $Scrape.getAllTopics(tab,p)
});
and below is express's(if I'm not wrong):
router.get('/',function(){
$data.getUserInfo(function(user){
$data.getContent(function(content){
res.render('index',{
userinfo:user,
content:content
})
})
})
})
see the differenent?
Express is callback,callback,callback!
and my solution is got a dependenies named "co-express",it's said that koa also based on it,below is the code after I use co-express:
router.get('/', wrap(function *(req,res,next){
res.render('content',$.extend(req.staticRes,{
content: yield $data.getContent(),
userinfo: yield $data.getUserInfo()
}))
}));
it's looks great.
thanks myself :-)

Form Data is correct when POSTing in Angular, but req.body is empty in node?

I am trying to do a simple POST call to a RESTful API that I created. I am using Angular for the client-side, nodejs for the server, and mongodb+express+multer for the database.
When testing the back-end using POSTman, the objects are created correctly, getting data from the req.body. In my Angular controller's createProject method, I am printing out my formData right before POSTing to the API. The form data looks correct. When the correct form data is POSTed to the working server, the req.body shows up empty.
Here is my relevant server code:
app.use(express.static(__dirname + '/public'));
app.use(multer({ dest: 'public/uploads/'}));
router.route('/projects') // accessed at //localhost:8080/api/projects
.post(function(req, res) {
console.log(req.body); // returns empty set
var project = new Project();
project.name = req.body.name;
project.description = req.body.description;
project.newComments = 0;
project.newPosts = 0;
//project.imageURL = req.body.imageURL;
project.save(function(err) {
if (err)
res.send(err);
Project.find(function(err, projects) {
if (err) res.send(err);
res.json(projects);
});
});
})
app.use('/api', router);
Here is my relevant Angular code:
$scope.createProject = function() {
console.log($scope.formData); // returns correct **{name: "adawda", description: "dawdaw"} **
$http.post('/api/projects', $scope.formData)
.success(function(projectData) {
$scope.formData = {};
$scope.imageURL = "";
$scope.projects = projectData;
console.log(projectData);
})
.error(function(projectData) {
console.log('Error: ' + projectData);
});
};
Here is my relevant HTML code:
<input type="text" placeholder="name of project" ng-model="formData.name" />
<input type="text" placeholder="description" ng-model="formData.description" />
<button type="submit" class="button" ng-click="createProject()">Create Project</button>
The Question:
How does Angular pass data from the $scope.formData to the request, and why is it not compatible with my server configuration? I'm pretty sure it has to do with the content-type in my POST, and how that relates to multer.
Thanks for your time!
You can use body parser middleware
app.use(bodyParser());

Resources