sfarzoso
sfarzoso

Reputation: 1600

How to display ajax error using partial view?

I wrote a really basic NodeJS application that allow the user to login. Now I'm a newbie on NodeJS so I'm trying to understand how can I display the ajax error using a PartialView from the login view.

First, I have a view called signup.ejs:

<div class="row">
    <div class="col-lg-5 d-none d-lg-block bg-register-image"></div>
    <div class="col-lg-7">
    <div class="p-5">
        <div class="text-center">
        <h1 class="h4 text-gray-900 mb-4">Signup!</h1>
        </div>
        <div id="errors">
            <% include ../partial/messages %>
        </div>
        <form class="user">
        <div class="form-group">
            <input
                type="username"
                id="username"
                name="username"
                class="form-control form-control-user" 
                placeholder="Username" />
        </div>
        <div class="form-group row">
            <div class="col-sm-6 mb-3 mb-sm-0">
                <input
                type="password"
                id="password"
                name="password"
                class="form-control form-control-user" 
                placeholder="Password" />
            </div>
        </div>
        <button id="register" class="btn btn-primary btn-user btn-block">
            Register Account
        </button>
        </form>        
    </div>
    </div>
</div>

<script src="/js/app/user/login.js"></script>

as you can see I loaded the PartialView called messages before the form declaration, and at the bottom of this view I have included the login script that handle the ajax request:

$("#register").click(function (event) {
    event.preventDefault();

    let regData = 
    {
        'username': $("#username").val(), 
        'email': $('#email').val(), 
        'password': $("#password").val()
    };

    $.ajax({
        type: 'POST',
        contentType : "application/json",
        url: '/user/signup',
        data: JSON.stringify(regData),
        dataType : 'json',
        success: function (data) {
            alert('hello');
            console.log(data);
        }, 
        error: function(jqXHR, textStatus, errorThrown){
            //How to display in partial here?
        }
    });
});

the ajax request will send the user data to user/signup route:

const userController = require('../controllers/user.controller.js');
router.post('/signup', userController.save);

that route call the function save of userController:

exports.save = function (req, res) {
    let user = new User();
    user.username = req.body.username;
    user.email = req.body.email;
    user.password = req.body.password;
    user.passwordConfirm = req.body.passwordConfirm;

    //Validate
    let errors = validate(user);

    //All was fine
    if (!errors) {
        //todo
    }
    else {
        res.status(500).send({errors: errors});
    }
};

this function simply validate the data before insert it in MongoDB, if the validation fails, then I return the errors generated by the validation method, that simply contains an array of objects, eg:

[
   { msg: 'Password mismatch' },
   { msg: 'Username length less than 6' }
]

Now I want display that messages at the top of the form, using the PartialView called messages:

<% if(typeof errors != 'undefined'){ %> <% errors.forEach(function(error) { %>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
    <%= error.msg %>
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
        <span aria-hidden="true">&times;</span>
    </button>
</div>
<% }); %> 

How can I do this using ajax?

Possible Solution

I fixed using this:

res.render('partial/messages', { errors: errors, layout: false});

this will return the error structure and then using ajax:

 error: function(jqXHR, textStatus, errorThrown){
     $('#errors').append(jqXHR.responseText);
 }

I don't know if this is a good solution, let's see if any of you have something better to propose.

Upvotes: 1

Views: 48

Answers (1)

Lord Elrond
Lord Elrond

Reputation: 16032

ejs is a template language that is used to insert values (variables, other templates, etc.) before a page is rendered on the client's browser. Any events that happen after the page has loaded can only be handled with javascript/jQuery.

The alternative to the asynchronous route you chose would be something like this:

change your form to this:

<form method="POST" action="/user/signup" class="user"> 
... //rest of the form goes here
</form>

then on your app.js:

app.post('/user/signup', function(req, res) {

    //handle user signup here

    const errors = validate(user);

    if (errors) {
    res.render('signup', {errors:errors});
    }
    else {
    res.render('somePageHere', {errors:false});
    }
});

Now you can access the error messages via ejs:

<% if (errors) { %>

    <% errors.forEach(function(error) { %>

        <div class="errors"> <%= error.msg %> </div>

    <% }); %>

<% } %>

Upvotes: 1

Related Questions