EAzevedo
EAzevedo

Reputation: 791

How can I send the data collected from a form and send it to another api route? JQuery, Node.Js API

I have a html page with a simple form. This page is loaded as the '/' index of my application.

with this script:

$(document).ready(function(e){
    $('#auth').on('submit',function(){
        getValues();
    });
});

I call an external file that gets the value of the inputs and has the task to do a post request to my server on another route '/login'.

function getValues()
{
     var values= {};

     values.username = $("input[name='username']").val();
     values.password = $("input[name='password']").val();
     console.log(values);

     $.ajax({
         type: "POST",
         data :JSON.stringify(values),
         url: "/login",
         contentType: "application/json"
     });

 }

API Login route:

 app.get('/login', function(req, res){
          console.log("sent on request: ", req.body);
          if(req.body)
          { res.redirect('/me');}
         });

My problem is that the login page is not being called. I can not see the output of the req.body on the console.

How can I send the data collected from a form and send it to another api route redirecting the api to a third route?

EDIT:

 var send = $.post( "/login", values, function(data) {
        console.log( "1 success", data );
  })
  .done(function() {
        console.log( "2 success", data );
  })
  .fail(function(send, status, errorThrown) {
        console.log( "send ", send, "status ", status, "Thrown ", errorThrown );

            //send returns the listed object below
            //status returns only 'error'
  });

That call returns fail - console.log(error);

SECOND EDIT: That is what the fail returns:

Object { readyState: 0, 
       getResponseHeader: getResponseHeader(),
       getAllResponseHeaders: getAllResponseHeaders(),
       setRequestHeader: setRequestHeader(), 
       overrideMimeType: overrideMimeType(), 
       statusCode: statusCode(), 
       abort: abort(),
       state: state(), 
       always: always(), 
       catch: catch(), … }

Upvotes: 0

Views: 505

Answers (2)

plonknimbuzz
plonknimbuzz

Reputation: 2664

try this

login.html

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>login</title>
</head>
<body>
<form id="auth">
    username <input type="text" name="username" value="admin"> 
    password <input type="text" name="password" value="12345"> 
    <input type="submit" value="Login">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $('#auth').submit(function(e){
        e.preventDefault();
        var formdata = $(this).serializeArray();
        var btn = $(this).find('input[type="submit"]');
        var btnVal = btn.val();
        $.ajax({
            type: "POST",
            data : formdata,
            url: "/login",
            dataType: 'json',
            beforeSend: function(){
                btn.prop('disabled', true).val('Loading');
            },
            success: function(data){
                if(data.ok ==1){
                    btn.val('Success');
                    console.log('success');
                    window.location = '/welcome'; //redirect somewhere if success
                }else{
                    btn.val('Failed');
                    console.log('failed');
                    console.log(data.msg);
                }
                setTimeout(function(){
                    btn.prop('disabled', false).val(btnVal);
                },2000);
            },
            error: function(data){
                console.log('error');
                console.log(data.responseText);
                btn.val('Error');
                setTimeout(function(){
                    btn.prop('disabled', false).val(btnVal);
                },2000);
            }
        });
    });
});
</script>
</body>
</html>

index.js

var express = require('express'); //npm install express
var app = express();
var path = require('path');
var bodyParser = require('body-parser'); //npm install body-parser
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname + '/login.html'));
});

app.post('/login', function(req, res){
    console.log(req.body);
    var result = {'ok':0};
    if(req.body.username == 'admin' && req.body.password =='12345'){
        result.ok = 1;
    }else{
        result.msg = 'wrong username/password';
    }

    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify(result));
});

app.get('/welcome', function(req, res) {
    res.sendFile(path.join(__dirname + '/welcome.html'));
});

app.listen(8000);

welcome.html

welcome<br>
<a href="/">back to login</a>

after that run in cmd: node index.js

then open the browser: http://localhost:8000

1st question. how to catch success and error using jquery ajax?

answer: looks on login.html and find success and error

criteria:

  1. if server responds with HTTP code header 200, this responds will return on success callback. else will return on error

  2. sometimes, server result error but still send it as HTTP 200. for hack this one, i using dataType: 'json'. this means, the criteria for return on success callback is added. 1. has HTTP 200, 2. must be in the json format. else go to error callback.

  3. in the index.js you will see var result = {'ok': 0} this is the default value for server respond as json. if user pass matched. change result.ok = 1 if not matched, still keep result.ok=0 and give an extra argumentation (result.msg). in here i used wrong username/password in this case: client login.html will catch this respond to success callback but will trigger failed because result.ok=0 (not 1). And the last, if server throw an error for some reason, this reponds will never in json format (like error exception blabla line number xxxx). Everything that not in json format will catched by error callback in login.html. in the error i never use console.log(data), but console.log(data.responseText) because data will have so many object like in your screenshot, and the most usefull one is only data.responseText which will give human readable error message

  4. the last portion is we need to change respond header from default text/html to application/json (hei client, im json not html) using res.setHeader('Content-Type', 'application/json'); and then we convert var result from js object to json format using res.send(JSON.stringify(result));

2nd question. how to send data from <FROM> using jquery ajax and nodejs ?

answer: we need module express and body-parser

  1. send as json (javascript object or array)

    • in login.html we need to build object/array and send it using: data: JSON.stringify() and contentType: "application/json" exactly like what you did.
    • in index.js we need to load module express and body-parser (you must install it first). and then we need to use bodyParser.json() to be able parse request in the json format (which client sent). To use it we simply write this code: app.use(bodyParser.json()); then after that you can use req.body.username to get POST request
    • conclusion the requirement: data: JSON.stringify() + contentType: "application/json" + app.use(bodyParser.json())
  2. send it as url-encoded

    • send as urlencoded is send request as string. we can use serializeArray() or serialize() to get everything in <form> tag. in your example you need to catch every input name to var values. how if you have 10 input? you need to catch every input name before you send it to server. So we change data: JSON.stringify() to data: $('#auth').serializeArray()
    • because request send as string. so we remove contentType: "application/json"
    • in index.js we still need expres and body-parser. the different is we use app.use(bodyParser.urlencoded({ extended: false })); instead app.use(bodyParser.json()); to parse urlencoded. But you can left both exists. because maybe you want send it as urlencoded / json.
    • conclusion the requirement: data: $('#auth').serializeArray() + app.use(bodyParser.urlencoded({ extended: false }));

3rd question. how to send data to the 3rd routes

actually i dont know what you mean about this.because you need more specify the question. but maybe this example can explain that

modified of index.js

...

function test(name){
    console.log('my name is '+name);
}

app.post('/login', function(req, res){
    var result = {'ok':0};
    if(req.body.username == 'admin' && req.body.password =='12345'){
        result.ok = 1;
    }else{
        result.msg = 'wrong username/password';
    }

    test(req.body.username); //send to another function

    var foo = require("./other"); //include another file (other.js)
    var nameLength = foo.other(req.body.username); //run function other() from file other.js
    console.log(nameLength);

    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify(result));
});

...

other.js

function other(name) {
    console.log("console.log from other.js");
    return name.length;
}

exports.other = other;

Upvotes: 1

Miguel Calder&#243;n
Miguel Calder&#243;n

Reputation: 3091

When handling a POST request, use app.post, not app.get:

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

Upvotes: 0

Related Questions