iLiA
iLiA

Reputation: 3153

error message is not displayed asynchronously ajax

In my login/ signup form I had used jquery ajax and it did not work, when user inputs wrong info that does not exist in my mongo database it should add the error message in my div that user is not registered ( without reload of course) but instead of it it sends my error message like res.send method (in empty page) here is code

app.post('/login',
async (req, res) => {

    try {
        const { username, password } = req.body;
        const user = await User.findOne({ username, password }).select('-password').lean();
        if (!user) {
            res.status(500).send({error: "user is not registered"});

            return;
        }

        req.session.user = user; 
        res.redirect('/dash')  
        return res.status(200).send('Session ID: ' + req.sessionID);


    }
    catch (error) {
        res.status(500).send(error.message);
    }
});

nodeJS code

<body>
<form action="/login" method="POST"> 
    <input type="text" placeholder="username" name="username" id="username"> 
    <input type="password" placeholder="pass" name="password" id="password"> 
    <button type="submit" id="zaza">Login</button>
    <div id="errMsg"></div>
     <br/>
    or <strong><a href="/reg">Sign Up</a></strong>
  </form>
  <script type="text/javascript">

    $('#zaza').on('click', function(event) {
event.preventDefault();
const username = $('#username').val(), password = $('#password').val();

$.ajax({
type: 'POST',
data: { username: username, password: password },
url: 'http://localhost:8080/login',
success: function(sessionID) {
  console.log(sessionID);
},
error: function(xhr, status, err) {
  const errMsg = xhr.responseText; // Your error msg
  $('#errMsg').html(errMsg);
 }
 });
 });

</script>

ajax code

error message

Upvotes: 1

Views: 54

Answers (1)

num8er
num8er

Reputation: 19372

You cannot send redirect and status with message at same time.

Better detect if request is ajax, json or not and depending on requirement respond with proper response.

So here is fix:

1) Fix server-side code:

app.post('/login', async (req, res) => {
    try {
        const {username, password} = req.body;
        const user = await User.findOne({username, password}).select('-password').lean();
        if (!user) {
          return res.status(404).send({
            message: 'user is not registered'
          });
        }

        req.session.user = user;

        const redirectTo = '/dash';

        if (
          req.is('json') // request content type is json
          || // or
          req.xhr // is ajax
        ) { 
          // respond with json response
          return res.status(200).status({redirectTo});
        }

        // not ajax request 
        // then respond redirect header
        res.redirect(redirectTo);
    }
    catch (error) {
        res.status(500).send({
          message: error.message
        });
    }
});

2) Fix client-side code:

<form id="login" action="/login" method="POST"> 
  <label>
    Username: 
    <input type="text" name="username" value="">
  </label> 

  <label>
    Password:
    <input type="password" name="password" value="" autocomplete="off"> 
  </label>

  <button type="submit">Login</button>
  <br/>
  <div class="error"></div>
</form>

<script type="text/javascript">
$(function() {

  var $loginForm = $('form#login');

  // handle form submit event
  $loginForm.on('submit', function(e) { 
    e.preventDefault(); // prevent browser doing default post

    $.ajax({
      type: $loginForm.attr('method'), // get method from form tag
      url: $loginForm.attr('action'),  // get action url from form tag
      data: $loginForm.serialize(),    // sending url-encoded string from fields

      // something went wrong
      error: function(xhr, textStatus, error) {
        try {
          var response = JSON.parse(xhr.responseText); 
          if (response.message) { // if json response has message field
            $loginForm.find('.error:first').html(response.message);
          }
        }
        catch (error) { // tried to parse response string as json, but could not - then just put error string to div
          $loginForm.find('.error:first').html(xhr.responseText);
        }
      },

      success: function(response) {
        if (response.redirectTo) {
          window.location.href = response.redirectTo;
        }
      }
    });

  });

});
</script>

References:

1) jQuery preventDefault

2) jQuery serializeArray

3) jQuery $.ajax fields and explanation

4) ExpressJS detect ajax request

5) ExpressJS req.is

Upvotes: 1

Related Questions