JADE form submit not caught although route exists - javascript

I am using JADE, node.js, and express to create a table to select some data.
Everything is running on localhost.
When I try the route /climateParamSelect it works and displays what I would like to see including URL encoded elements.
Routing to this code snippet is in app.js but I confirmed that it works using /climateParamSelect?test=test. The routes are located in climateParamSelect.js
router.get('/', async function(req, res, next) {
console.log('GET');
console.log(req.query);
});
router.post('/', async function(req, res, next) {
console.log('POST');
console.log(req.params);
});
module.exports = router;
The code in app.js may be important after all, so here is an excerpt:
const express = require('express');
var tableSelectRouter = require('./routes/tableSelect');
var cpSelectRouter = require('./routes/climateParamSelect');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/climateParamSelect', cpSelectRouter);
app.use('/tableSel', tableSelectRouter);
When I use the submit button of the following page it is invoked but for some reason, the route above is never taken. Instead, it displays: waiting for localhost.
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet', href='https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css')
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js')
script(src='https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js')
script.
$(document).ready(function() {
$('#selTable').DataTable();
});
body
form(name='productionSelect', method='post', action='/climateParamSelect')
div#wrapper
h1 Select production data for feature generation
br
table#selTable.display
thead
tr
th headers
//...
tbody
tr
td
input(type='checkbox',id='#{r}',name='#{r}')
td
//...
br
input(type='submit',value='Select Production',name='prodSubmit',data-transition='fade', data-theme='c')
What am I missing here?
Thank you

The browser will sit there spinning until it receives a response, and there is no response sent in your route. I'm sure you'll want to render a view, but to test it quickly just use res.send and a string.
The second issue is in how you're reading the data sent from the client. req.params is used for dynamic URL parsing with variables in the route. To handle form data (which is what you're sending here) you can use req.body.
Changing your route to this should fix your issues:
router.post('/climateParamSelect', async function(req, res, next) {
console.log('POST');
console.log(req.body);
res.send("hello");
});

Related

ExpressJs static files not working correctly

I have an express app and the static files are not working for every route.
When I get to '/', the static styles and images work perfectly when index.ejs is rendered.
When I get '/efbhew', a route that doesn't exist, 404.ejs renders ok.
When I get '/asdw/feff' or other routes like '/df/fg/dfgdfg/sfgd', the static styles and images do not work. Is there something else I have to do in order for it to work?
Below is my code.
const app = express();
app.use(express.static(path.join(__dirname, '../public')));
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(express.json());
app.get('/', async (req, res) => {
const posts = await Post.find({}).limit(7).sort({ createdAt: -1 }).exec();
res.render('index.ejs', {
latestPosts: posts
});
});
app.get('*', (req, res) => {
res.render('404.ejs');
});
This is the structure of my folders:
I tried changing the path of the public folders to go deeper since when I got to '/asdf/wfds/sdfsd', the image source is 'http://localhost:3000/asdf/wfds/img/logo.png' and it cant find it. But that still didn't work.
When an ejs page at /df/fg/dfgdfg/sfgd references a static file, as in
<img src="img/logo.png"/>
the URL is relative to the URL of the ejs page, so in this example it would be /df/fg/dfgdfg/img/logo.png (note the last segment sfgd is dropped, that's why it works for a page at /efbhew).
But the image exists only as /img/logo.png. Therefore, you should always address it with a path that starts with a slash, as in
<img src="/img/logo.png"/>

Express Renders Pug File to Same URL?

When I fill out my form and submit my data, it renders my order.pug file on the browser, but my URL is still showing just localhost:3000 instead of localhost:3000/order?
My pug file is in a views folder and my express.js file is just on the main directory for my project
Here is my express file
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static(__dirname + "/public"));
app.set("view engine", "pug");
app.get("/orderPug", (req, res) => {
res.render("orderPug");
});
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "index.html"));
});
Then my post request to accept my data, then render my order.pug file
app.post("/create", async (req, res) => {
//API Authentication code is here
res.render("order")
});
My Pug File looks like this, so if I just navigate to localhost:3000/order it will show the value hard coded like below.
h1 Total: $#{totalCost}
But after I submit my form data it ends up looking like this, except the URL is still on localhost:3000
Total: $100.00
So when I submit my form, it shows the page has updated to order.pug yet the URL still just shows localhost:3000 and I don't think that makes sense for a confirmation page to show?

How can I access the input form results in an html form?

I am trying to import my project into a nodejs app where I will be able to run the website on a localhost. This works, because when I run index.js and enter the url 'http://localhost:8080/', it redirects me to the homepage of my website.
The problem is, I have a form on my website, and I am trying to access the Feedback.html page where the form resides. What I am trying to do is upon submission, the form data is returned, and the data prints to the terminal (console.log()). If you look at my code, I believe that it is right. However, I am not sure where I need to place my Project4 directory. Should I place it in my views folder?
I am confused on why I need a views folder. Also, my form submission code is unresponsive.
const path = require('path');
const fs = require('fs');
const bodyParser = require('body-parser');
const { render } = require('pug');
const app = express();
//middleware and routing
app.set('view engine', 'pug');
app.use(bodyParser.urlencoded({ extended: true }));
//Viewing website
app.use('/Project4', express.static('Project4'));
app.get('/', function(req, res){
res.redirect('/Project4/index.htm');
});
//------------------------------
//***FORM SUBMISSION PART***
app.get('/Project4/Feedback.html', function(req, res){
res.render('Project4/Feedback.html');
});
app.post('/submit-form', function(req, res){
console.log(req.body);
res.end();
});
//------------------------------
const PORT = process.env.PORT || 8080;
app.listen(PORT, function(error){
if(error){
console.log('Issue with server on port ' + PORT);
}
else{
console.log('Server running on port ' + PORT);
}
}); ```
[![This is what my app folder looks like. Where do I place the Project4 folder so that I can access its form via post method?][1]][1]
[1]: https://i.stack.imgur.com/CzC8p.png
In your form (please include the form as well), the name of the thing you want to access is very important. Using a npm package called body-parser (do npm i body-parser then const bodyParser = require("body-parser"). This basically just extracts the entire body portion of an incoming request stream and exposes it on req.body. Now you have body parser setup, you just need the name of the input (e.g feedback) and do this
console.log(req.body.feedback)
in the app.post route. And you should be set! The thing i should mention though is that the form should have the method of POST, the route is correct and the button is a SUBMIT button. Here is what I would have done.
The form (HTML)
<form action="/" method="post">
<input type="text" name="feedback" placeholder="Your Feedback">
<button type="submit">Submit feedback</button>
</form>
App.js
const express = require('express');
const bodyParser = require("body-parser");
const app = express();
//Those were the modules
app.use(bodyParser.urlencoded({ extended: true }));
//use body parser with the urlencoded extended
app.get("/", function(req, res){
res.sendFile(__dirname + "/index.html");
});
//sends the index.html when going to home route (/)
app.post("/", function(req, res){
var feedback = req.body.feedback;
console.log(feedback);
res.redirect("/")
});
// when posted, we make a variable requesting the body, and then the name of the input, which is the name part of the input.
app.listen(3000, function(req, res){
console.log("Server started on port 3000");
}); //self-explanatory.
One last thing. Your views folder is needed because you are using a view engine. Take EJS; if I used res.render(index, {feedbackstuff: feedback}), then the index file would need to be a .ejs file and in the views folder.

Express Render not working return error: No default engine was specified and no extension was provided

I'm writing an Express application without a template engine I am using just using HTML as the template engine.
app.set('view engine', 'html');
actually, the whole code was generated using express-generator and I set the view to --no-view Flag and the index URL page runs well but trying another URL like users or any other except the index URL does work all it shows is
No default engine was specified and no extension was provided.
But if I Add the above code app.set('view engine', 'html'); it returns
Error: Cannot find module 'html'. Below are the codes.
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var addressRouter = require('./routes/address');
var app = express();
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
module.exports = app;
And the userRouter user.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
For Home Page
router.get('/', function(req, res, next) {
res.render('index');
});
Can someone please tell what is wrong here.
To serve html you do not need to use the view engine, just use express.static, as you are already using
app.use (express.static (path.join (__ dirname, 'public')));
As #Henrique said, you are already able to render staticHTML. What’s tripping you up is the res.render calls. Those specifically exist to call a template. Switch to res.send and your error should go away.
What I did was with sendFile on the route controller like the userRoute controller
res.sendFile(path.resolve(__dirname,'../public/index.html'));
and I remove the set engine
app.set('view engine', 'html');
But the index page works perfectly without the above tweak.

How can I use Handlebars with Express?

The question is actually not difficult to understand, I do not know how to implement handlebars in Express.
That's what I've already coded:
var express = require('express');
var app = express();
app.get('/', function (req, res, next) {
return res.render('index');
});
Now is my question, how to set handlebars as app engine for express?
Here is the code as I currently use and learned. I have added a note behind every important line so that you understand it well!
var express = require('express');
var app = express();
var handlebars = require('express-handlebars');
app.engine('handlebars', handlebars({ // Here we define what format you will use (That means what's at the end of each file, for example test.handlebars or test.hbs)
defaultLayout: 'main', // That's the name of your template file. In my case it's main.handlebars
layoutsDir: __dirname + '/views/layouts/' // That's the directory where the template file is
}));
app.set('views', path.join(__dirname, 'views')); // Here you give express the information that it has to look at all files that are in the path /views
app.set('view engine', 'handlebars'); // Here you say express that you are using handlebars to build your website
app.get('/home', function (req, res, next) { // That's a simple GET request (This GET request gets triggered when you enter http://localhost/home for example)
return res.render('index'); // Here we render the index.handlebars file (that is in the /views folder)
});

Categories

Resources