简体   繁体   中英

NodeJS res.render not working when posting EJS form data

I am trying to render a page after form data is submitted. There is no error message, it just isn't rendering the page. The page seems to refresh but nothing else. The res.render for the get request is working, verifying the path for pages is correct.

I originally suspected that the.preventdefault() and/or the.submit() functions were the problem but the page does refresh when all validations have passed. FYI the validations are that all field must contain something, email must be valid, passwords must match and passwords must be between 5 and 20 characters long.

Note: signup.ejs has some client side validation on it.

signupRoutes.js

const express = require('express');
const router = express.Router();

const renderSignup = require('../controllers/signupController.js');
const postSignupData = require('../controllers/signupController.js');

router.get('/', renderSignup);
router.post('/', postSignupData);

signupController.js

renderSignup = (req, res) => {
    res.render("signup");
};

postSignupData = (req, res) => {
    res.render("verify-email");
};

module.exports = renderSignup, postSignupData;

module.exports = router;

server.js

const express = require('express');
const app = express();
const ejs = require('ejs');
const path = require('path');

app.use(express.static('../frontend/public'));

app.use(express.json());
app.use(express.urlencoded({ extended:true }));

app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../frontend/pages'));

const signupRoutes = require('./routes/signupRoutes.js');
const verifyEmailRoutes = require('./routes/verifyEmailRoutes.js');

app.use('/signup', signupRoutes);
app.use('/verify-email', verifyEmailRoutes);

const port = 4000
app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
})

signup.ejs

<head>
   <link rel="stylesheet" href="css/style.css">
   <title>Signup</title>
</head>

<body>
<h1>Signup</h1>
<form method="post" action="/signup" id="signupform">
    <label for="email">Email:</label>
    <input id="email" type="text"><br><br>
    <p class="error-msg" id="error-msg-empty-email">Email Cannot be Empty (Client Side Validation)</p>
    <p class="error-msg" id="error-msg-invalid-email">Email is not Valid (Client Side Validation)</p>
    <label for="password">Password:</label>
    <input id="password" type="password"><br><br>
    <p class="error-msg" id="error-msg-empty-password">Password Cannot be Empty (Client Side Validation)</p>
    <p class="error-msg" id="error-msg-password-character-limits">Password must be between 5 and 20 characters (Client Side Validation)</p>
    <label for="password">Confirm Password:</label>
    <input id="confirm-password" type="password"><br><br>
    <p class="error-msg" id="error-msg-password-mismatch">Passwords do not match (Client Side Validation)</p>
    <input id="signupsubmit" type="submit">
</form>
<a href="signin">Go to signin page!</a><br>
<a href="/">Go to home!</a>

<script>
    const signupform = document.getElementById("signupform");

    const errorMsgEmptyEmail = document.getElementById("error-msg-empty-email");
    const errorMsgInvalidEmail = document.getElementById("error-msg-invalid-email");
    const errorMsgEmptyPassword = document.getElementById("error-msg-empty-password");
    const errorMsgPasswordMismatch = document.getElementById("error-msg-password-mismatch");
    const errorMsgPasswordCharacterLimits = document.getElementById("error-msg-password-character-limits");

    signupform.addEventListener('submit', (e) => {

        e.preventDefault();
        checkInputs();
        if(errorCount === 0){
            signupform.submit();
        }
    });

    function checkInputs () {
        const email = document.getElementById("email").value.trim();
        const password = document.getElementById("password").value.trim();
        const confirmPassword = document.getElementById("confirm-password").value.trim();

        errorCount = 0;

        if(email === ''){
            errorMsgEmptyEmail.style.display = "block";
            errorCount++;
        } else{
            errorMsgEmptyEmail.style.display = "none";
            
            const regx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
            
            if(email.match(regx)) {
                errorMsgInvalidEmail.style.display = "none";
            }else{
                errorMsgInvalidEmail.style.display = "block";
                errorCount++;
            }
        }

        if(password === ''){
            errorMsgEmptyPassword.style.display = "block";
            errorCount++;
        } else{
            errorMsgEmptyPassword.style.display = "none";
        }

        if(password != confirmPassword){
            errorMsgPasswordMismatch.style.display = "block";
            errorCount++;
        } else{
            errorMsgPasswordMismatch.style.display = "none";
        }
        
        if(5 <= password.length && password.length <= 20){
            errorMsgPasswordCharacterLimits.style.display = "none";
        } else{
            errorMsgPasswordCharacterLimits.style.display = "block";
            errorCount++;
        }
    };
</script>

Here is my folder structure

  • Backend
    • server.js
    • routes
      • signupRoutes.js
    • controllers
      • signupController.js
  • Front End
    • pages
      • signup.ejs
      • verify-email.ejs
    • public
      • css
      • style.css

The problem could be in the following source code:

 signupform.addEventListener('submit', (e) => {

        e.preventDefault();
        checkInputs();
        if(errorCount === 0){  // errorCount is not defined here
            signupform.submit();
        }
    });

The errorCount variable is not defined in the callback. It is defined in the checkInputs() function, but is not returned.

To solve this, you can define the variable before calling checkInputs() like so:

  signupform.addEventListener('submit', (e) => {

        e.preventDefault();
        errorCount = 0;  // define the variable here
        checkInputs();
        if(errorCount === 0){
            signupform.submit();
        }
    });

    function checkInputs () {
        ...
        const confirmPassword = document.getElementById("confirm-password").value.trim();

        // remove the variable here
        ...

Another way, you can modify checkInputs() to return the errorCount variable like so:

    function checkInputs () {
        const email = document.getElementById("email").value.trim();
        const password = document.getElementById("password").value.trim();
        const confirmPassword = document.getElementById("confirm-password").value.trim();

        errorCount = 0;
        ...
        return errorCount;      // at the end of the function

Then stored the returned value in the errorCount variable:

 signupform.addEventListener('submit', (e) => {

        e.preventDefault();
        errorCount = checkInputs();   // store returned value
        if(errorCount === 0){ 
            signupform.submit();
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM