Home > Net >  variable is undefined on ejs file
variable is undefined on ejs file

Time:04-09

Im having a little problem on one proyect, Im using ejs as a template engine and expressjs as server framework, so the problem come when Im validating that the user data were correct and I pass a const with the errors that will can occur when the data are validated, example: (password lenght, a email exist... etc), (Im using mongoose as ODM).

Here is the get route:

router.get("/login-register", (req, res) => {
    res.render("login-register");
});

And here is the code from the post route:

router.post("/login-register", async (req, res) => {
const userRegisterFetched = usersSchm(req.body);

// Save the user data from a html form and declare a empty const where im going to put the errors
await userRegisterFetched.save();
const errorToClient = [];

// If the password lenght arent coincide with the if statement throw an error
if(userRegisterFetched.password.length <= 0) {
    errorToClient.push("The password cannot be empty");
    } else if(userRegisterFetched.password.length < 8) {
        errorToClient.push("The password must have 8 characters at least!");
    };

// If the passwords dont coincide it throw an error
if(userRegisterFetched.repeat_password !== userRegisterFetched.password) {
    errorToClient.push("The password dont coincide");
    } else if(userRegisterFetched.password !== userRegisterFetched.repeat_password) {
        errorToClient.push("The password dont coincide");
    };

In the next line is when i pass the const after the data validation to the .ejs file, but after the .ejs file return that the var are not defined

if(errorToClient.length > 0) {
    res.render("login-register", { errorToClient });
    } else {
        res.send("OK")
    };

Later, i use a forEach statement to show the errors that was saved in the array const

<% errorToClient.forEach((errorToClient) => {%>
    <div >
        <h3><%= errorToClient %></h3>
    </div>
    <%}
)%>

And when i visite the route "/login-register" i get this:

ReferenceError: E:\JavaScript\web_foor\src\views\pages\login-register.ejs:2
    1| <%- include ("../partials/main-header") %>

 >> 2| <% errorToClient.forEach((errorToClient) => {%>

    3|         <div >

    4|             <h3><%= errorToClient %></h3>

    5|         </div>
errorToClient is not defined
    at eval ("E:\\JavaScript\\web_foor\\src\\views\\pages\\login-register.ejs":13:8)
    at login-register (E:\JavaScript\web_foor\node_modules\ejs\lib\ejs.js:692:17)
    at tryHandleCache (E:\JavaScript\web_foor\node_modules\ejs\lib\ejs.js:272:36)
    at View.exports.renderFile [as engine] (E:\JavaScript\web_foor\node_modules\ejs\lib\ejs.js:489:10)
    at View.render (E:\JavaScript\web_foor\node_modules\express\lib\view.js:135:8)
    at tryRender (E:\JavaScript\web_foor\node_modules\express\lib\application.js:640:10)
    at Function.render (E:\JavaScript\web_foor\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (E:\JavaScript\web_foor\node_modules\express\lib\response.js:1017:7)
    at E:\JavaScript\web_foor\src\routes\/index.routes.js:25:9
    at Layer.handle [as handle_request] (E:\JavaScript\web_foor\node_modules\express\lib\router\layer.js:95:5)

Thanks in advance :)

CodePudding user response:

When you are visiting "/login-register" route, the request hits this:

router.get("/login-register", (req, res) => {
    res.render("login-register");
});

and there is no errorToClient defined. You can write your own middleware to display error using req.session and res.locals objects by the express-session module or you can use express-flash or connect-flash. I prefer connect-flash.

After installing connect-flash you can simply use it in your application by adding these two lines in your app.js file:

var flash = require('connect-flash');
 
app.use(flash());

Then use it in your route handler functions, simply redirect after an error occurs:

    if(userRegisterFetched.password.length <= 0) {
        req.flash("errorToClient","The password cannot be empty");
        return res.redirect("/login-register");
    } else if(userRegisterFetched.password.length < 8) {
        req.flash("errorToClient","The password must have 8 characters at least!");
        return res.redirect("/login-register");
    } else {
        res.send("ok");
    }

Also change your get route like this:

router.get("/login-register", (req, res) => {
    let message = req.flash('errorToClient');
    if (message.length > 0) {
        message = message;
    } else {
        message = null;
    }
    res.render("login-register", {errorToClient: message});
});

In your ejs:

<% if(errorToClient) { %>
   <% errorToClient.forEach((errorToClient) => {%>
      <div >
        <h3><%= errorToClient %></h3>
      </div>
   <% }) %>
<% } %>

You can also skip the for loop in ejs by printing only the latest error. Just change this line in "/login-register" route handler:

if (message.length > 0) {
    message = message[0];
}

And in ejs change the error block to this:

<% if(errorToClient) { %>
   <div >
      <h3><%= errorToClient %></h3>
   </div>
<% } %>

CodePudding user response:

I have had this issue before, I solved it by using connect-flash module.

Check npmjs.com for more information: https://www.npmjs.com/package/connect-flash

  • Related