I stuck in figuring out how client file find routes function in express. My app structure is like that,
|-root
|--public
|---files
|---scripts
|---css
|--views
...
The client side html is as blow, which is in /public/files. It can be rendered to http://localhost:3000/files/like_animal.html correctly.
<html>
<body>
<form action="/handleForm" method="post">
name: <input name="usename"><br>
I like <input name="animal"><br>
<input type="submit" value="Go">
</form>
</body>
</html>
The js file is like that,
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname + 'public')));
console.log('start');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/handleForm', (req, res) => {
var name = req.body.name;
var animal = req.body.animal;
console.log(name + " " + animal);
res.send('Thank you');
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
Now I am not sure where I should put this js file in. I tried to put it in /public/scripts or root, even also in /public/files. But nothing works. Every time I submit the form, the browser always show Cannot POST /handleForm. As a one-week newbie in express, I am totally lost. Any hint will be appreciated. Thanks a lot.
You should put your script at the root then specify the public's path like this.
app.use(express.static(path.join(__dirname, 'public')));
Another note, app.use is used to make a middleware. You should define your route using app.post.
app.post('/handleForm', (req, res) => {
// ...
});
Related
I have a simple node script in which I update the db.json file through the form. It updates the file but when I render it in response for a get or post out it gives previous results only.
var cors = require('cors')
const express = require('express');
const app = express();
var jsonfile = require('jsonfile');
var file = './db.json'
var filex = require('./db.json')
app.engine('html', require('ejs').renderFile);
app.use(cors())
const http = require('http');
const port = process.env.PORT || 3000
const bp = require('body-parser')
app.use(bp.json())
app.use(bp.urlencoded({ extended: true }))
app.set('view engine', 'html')
// Defining get request at '/' route
app.get('/', function(req, res) {
res.send("<html><head><title>Json</title></head><body><form id='form1' action='/gettingdata' method='post'><input type='text' name='usrid' /><button type='submit' form='form1' value='Submit'>Submit</button></form></body></html>")
});
app.post('/gettingdata',function(req,res){
var user_id = req.body.usrid;
var obj = JSON.parse(user_id)
jsonfile.writeFileSync(file, obj,{flag: 'w'});
res.send('updated');
})
app.post('/api',function(req,res){
res.send(filex)
})
app.get('/api',function(req,res){
res.send(filex)
})
//extra
app.post('/api/v1/users/initial_authentication',function(req,res){
res.send(filex)
})
app.get('/api/v1/users/initial_authentication',function(req,res){
res.send(filex)
})
app.listen(port, function(req, res) {
console.log("Server is running at port 3000");
});
It only gives updated results on redeveloping of server.
var filex = require('./db.json')
So, filex only load the file when the server starts. If you try to get the most updated content of file db.json, please re-load the file.
I guess res.send(require('./db.json')) may work as expected.
I have solved this issue using
delete require.cache[require.resolve('./db.json')]
I have recently started picking up Node.js with the Express framework. I created a simple server and attached an HTML file with a form consisted of a single button of type submit which was supposed to send a post request to the server. It doesn't give me any errors but when I try to log a message to the console upon pressing the submit button, nothing happens. I am pretty sure it has something to do with the HTML form syntax but I can never be too sure. Here is the HTML:
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<form class="test" action="http://localhost:8000/example" method="post">
<input type="submit" name="but" value="Press me">
</form>
</body>
</html>
Here is the Express code:
const http = require("http");
const app = require("express")();
const path = require('path');
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/example", (req, res) => {
console.log("pressed");
});
app.listen(8000, ()=>{
console.log("Running at 8000");
});
It's occurs because app.use () is treated as middleware for your application. To work properly you should use app.get (). Here is more detailed explanation. Other alternative is provide your html as an static content, you can see more about here.
To work properly you should change your code to this:
app.get("/", (req, res) => {
res.sendFile(__ dirname + "/index.html");
});
You can also modify your HTML to this:
<form class="test" action="/example" method="post">
Because is in the same host. You just use complete url when performing action to other host.
Change this...
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
to this...
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
I am new learning NodeJS + Express and now I am trying to build a simple register form but I keep getting the same error with this and other forms:
Cannot POST /registerauth
I have looked through dozens of similiar questions in stackoverflow and other sites but I have not found an answer that applies for my case.
Here is the form:
<form id="register-form" class="panel-form" action="/registerauth" method="POST">
<input type="text" name="register-username" id="register-username" class="fill-input" placeholder="Username *" autofocus="true" maxlength="15" required>
<input type="password" name="register-password" id="register-password" class="fill-input" placeholder="Password *" maxlength="30" required>
<button type="submit">Register</button>
</form>
My app.js file:
const express = require('express');
const app= express();
const path = require('path');
const port = process.env.PORT || 3000;
const login = require('./routes/login'); /*MODULE THAT HAS THE CONTROLLER CODE*/
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname , 'public')));
app.post('/registerauth',function (req,res,next){ /*TRIED THIS BUT DIDN'T WORK*/
console.log("testing");
res.json(req.body);
})
app.use('/login', login); /*TRIED CALLING THE MODULE THAT HAS THE CONTROLLER AND DELETING THE LINE ABOVE BUT DIDN'T WORK*/
app.listen(port, ()=> console.log(`server started on port ${port} `))
The module that has the controller code but it's not even called :
const express = require('express');
const oracledb = require('oracledb');
const router = express.Router();
const dbConfig =require('../dbconfig.js') ;
class Cliente{
constructor(username,password,nombre,email){
this.username = username;
this.password=password;
this.nombre=nombre;
this.email=email;
}
}
let conexion;
router.post('/registerauth',async(req,res,next)=>{ /*all this is not working neither*/
try{
console.log("THIS IS NOT WORKING");
cliente = new Cliente(req.body.username, req.body.password,req.body.nombre,req.body.email);
conexion= await oracledb.getConnection(dbConfig);
const result = await conexion.execute(
`INSERT INTO Cliente values (${cliente.username}, ${cliente.password},
${cliente.nombre}, ${cliente.email})`
);
} catch(err){
console.error(err);
}finally{
conexion.close();
}
})
module.exports = router;
And I have my project folder structured this way:
/
node_modules
public/
css/
media/
scripts/
index.html (just the file inside public folder)
register.html (just the file inside public folder THIS IS THE REGISTER FORM FILE)
routes/
api/
login.js
app.js
dbconfig.js
package-lock.json
package.json
Note: I created other forms in my project with different action methods and all of them gave the same error
this is the whole idea:
const express = require("express")
const app = express()
const router = require("./router")
app.use(express.static("public"))
app.use(express.urlencoded({extended: false}))
app.use(express.json())
app.use('/', router) // write all your routes in this file 'router'
module.exports = app
You need to render the HTML file in your server on port '3000'. I think you are trying to access 'http://localhost:3000/registerauth' directly while rendering the html page outside the server.
Make these changes to App.js file
const express = require('express');
const app= express();
const path = require('path');
const port = process.env.PORT || 3000;
const login = require('./routes/login'); /*MODULE THAT HAS THE CONTROLLER CODE*/
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
//newly added code
app.get('/',(req,res)=>{
res.sendFile('index.html');
})
app.post('/registerauth',function (req,res,next){ /*TRIED THIS BUT DIDN'T WORK*/
console.log("testing");
res.json(req.body);
// Redirect to '/login' here instead of sending response which will trigger the login module
})
app.use('/login', login); /*TRIED CALLING THE MODULE THAT HAS THE CONTROLLER AND DELETING THE LINE ABOVE BUT DIDN'T WORK*/
app.listen(port, ()=> console.log(`server started on port ${port} `))
Render the html page when you hit 'http://localhost:3000'. Also, inorder for your login component to work you need to redirect to '/login/' path in the POST request
I have made super simple code for the sole purpose of receiving data from the client.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var PORT = 80;
app.get('/',function(req,res){
res.send('<form action="/" method="post"> <input type="text"name="firstname" value="Mickey"><input type="submit" value="Submit"> </form>');
});
app.post('/', function (req, res) {
console.log(req.body.firstname);
res.send('POST request to the homepage');
});
app.listen(PORT, () => console.log("Listening on port "+PORT));
That is it. but when I run it it says that req.body.firstname is undefined.
What am I doing wrong?
To parse form data, you'll have to use the bodyParser.urlencoded middleware.
Add the following to your code, before you handle the POST request:
app.use(bodyParser.urlencoded({ extended: false }));
I've created a node application with express. I try to separate the following layers which will give me the ability to test the application with unit testing...
The problem is that I don't know how to call to the router.js file which will stops in the post/get/delete application.
The server.js file looks as follows
http = require('http'),
app = require('./app')(),
http.createServer(app).listen(app.get('port'), function (err) {
console.log('Express server listening on port ' + app.get('port'));
});
This is the app.js file
var express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
routesApp = require('./ro/route');
module.exports = function () {
var app = express();
app.set('port', process.env.PORT || 3005);
app.use(logger('dev'));
app.use(function (req, res, next) {
res.set('APP', 'User app');
next();
});
app.use(bodyParser.json());
app.use(routesApp);
return app;
};
This is the router.js, which will route the call to other module according to the http type like post/delete/get etc...
var handleGet = require('../controller/handleGet');
var handlePost = require('../controller/handlePost');
var express = require('express');
module.exports = function (app) {
var appRoute = express.Router();
app.use(appRoute);
appRoute.route('*')
.post(function (req, res) {
handlePost(req, res);
})
.get(function (req, res) {
handleGet(req, res)
})
Currently I've two questions:
How to make it work since when in debug It dump in
app.use(appRoute); on the router.js file?
The error is TypeError: undefined is not a function
Is it good way to structure the node app like in my post? I want to seperate all this layers like SOC, I'm fairly new to node and express and I try to build it to be modular and testable...
How to make it work since when in debug It dump in app.use(appRoute); on the router.js file? The error is TypeError: undefined is not a function
This fails because you don't pass app into the module when you require it in app.js, you would need to do something like
app.use(routesApp(app)); // <- this hurts my eyes :(
Is it good way to structure the node app like in my post?I want to sperate all this leyrs like SOC,I fairly new to node and express and I try to build it to be modular and testable...
Your definitely on the right track, keeping things separated is generally always a good idea. Testing is definitely one of the big pluses but it also helps with other things like maintainability & debugging.
Personally, I would make use of the bin directory for any start up script configuration
bin/www
var app = require('./app');
app.set('port', process.env.PORT || 3005);
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
This will help decouple your express app from all the environment setup. This should keep your app.js clean and only contain app-related config
app.js
var express = require('express')
, app = express()
, logger = require('morgan')
, bodyParser = require('body-parser')
, routes = require('./routes.js');
app.use(logger('dev'));
app.use(function (req, res, next) {
res.set('APP', 'User app');
next();
});
app.use(bodyParser.json());
app.use('/', routes);
...
module.exports = app;
Then finally, your routes.js should do nothing but handle your URLs
routes.js
var express = require('express')
, router = express.Router()
, handleGet = require('../controller/handleGet')
, handlePost = require('../controller/handlePost');
router.get('/', handleGet);
router.post('/', handlePost);
...
module.exports = router;