Pratibha
Pratibha

Reputation: 1786

Send POST request to REST API via javascript

First, I read somewhere that we should not use XMLHttpRequest.

Second, I am a newbie in Javascript.

Third, I created a webpage to submit email and password.

<form method="POST" onsubmit="return check();">{% csrf_token %}
    <p><b>Login</b></p>
    <input type="email" name="email" placeholder="Email" required></input>
    <input type="password" name="password" placeholder="Password" id='new_password' ></input>
    <span id='message'>{{msg}}</span>
    <button type="submit" onclick="check()" name="Submit"><b>Submit</b></button>
</form>

My check function is

function check() {        
    document.getElementById('message').innerHTML = "checking";
    const url = "https://<hostname/login";
    const data = {
        'email' : document.getElementById('email').value,
        'password' : document.getElementById('password').value
    };

    const other_params = {
        headers : { "content-type" : "application/json; charset=UTF-8" },
        body : data,
        method : "POST",
        mode : "cors"
    };

    fetch(url, other_params)
        .then(function(response) {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error("Could not reach the API: " + response.statusText);
            }
        }).then(function(data) {
            document.getElementById("message").innerHTML = data.encoded;
        }).catch(function(error) {
            document.getElementById("message").innerHTML = error.message;
        });
    return true;
}

This code is not working and just redirects me to the same page again and again.

Please help me understand what am I doing wrong.

Upvotes: 5

Views: 39242

Answers (5)

jcmarin2298
jcmarin2298

Reputation: 41

The problem with your code is that you are not "intercepting" the submit event of your form so it will execute the default behavior which is POST to itself (since it doesn't have an instruction that tells it where to go). Unless you can have a chance to stop this default behavior, the form will perform this action.

To intercept the form's submit event you have to tell the browser to watch out of this event and execute a custom function instead of using an event listener like below:

<script>

document.getElementById('whatever-form-id')
  .addEventListener('submit', check);

function check(e) {
  e.preventDefault();
  // and now anything else you want to do.
}

</script>

This will prevent your form from posting and it will execute your function instead.

Upvotes: 4

mrgrechkinn
mrgrechkinn

Reputation: 908

1) Your validation function always returns true
2) When you use fetch..then, its promises can be executed later than return statement

So your form will be refresh again and again. You should return false, and manually submit the form with JavaScript when you get an onSuccess response.

<script>
    function check(event) {
        document.getElementById('message').innerHTML = "checking";

        const url = "https://localhost:8080/login";
        const data = {
            'email' : document.getElementById('email').value,
            'password' : document.getElementById('new_password').value
        };
        const other_params = {
            headers : { "content-type" : "application/json; charset=UTF-8" },
            body : data,
            method : "POST",
            mode : "cors"
        };

        fetch(url, other_params)
            .then(function(response) {
                if (response.ok) {
                    alert(response.json());
                } else {
                    throw new Error("Could not reach the API: " + response.statusText);
                }
            }).then(function(data) {
                document.getElementById("message").innerHTML = data.encoded;
            }).catch(function(error) {
                document.getElementById("message").innerHTML = error.message;
            });
        return false;
    }
</script>

<form method="POST" onsubmit="return check();">{% csrf_token %}
    <p><b>Login</b></p>
    <input type="email" id = "email" name="email" placeholder="Email" required></input>
    <input type="password" name="password" placeholder="Password" id='new_password' ></input>
    <span id='message'>{{msg}}</span>
    <button type="submit" name="Submit"><b>Submit</b></button>
</form>

Update:

Page not refreshed, error message displayed: enter image description here

Upvotes: 1

James Chen
James Chen

Reputation: 45

just going off the top of my head here but you've set the Content-Type to application/json in the headers but your body is not an JSON string

try making your body match the headers by doing

const other_params = {
  headers : { "content-type" : "application/json; charset=UTF-8"},
  body : JSON.stringify(data),
  method : "POST",
  mode : "cors"
};

EDIT

So after re-reading your question, I think what is happening is you've set your button to type of submit and what is happening is when you click on the button, your form is getting posted through the good old form post and your page gets refreshed from the postback.

If you want to handle form posts yourself using fetch, change your button type to button and the form should no longer actually post then everything else will be handled by your click event handler.

ps. while you're at it, you can remove the method and onsubmit attribute from your form tag as well

So your form should look something like this

<form>
    <p><b>Login</b></p>
    <input type="email" name="email" placeholder="Email" required></input>
    <input type="password" name="password" placeholder="Password" id='new_password' ></input>
    <span id='message'>{{msg}}</span>
    <button type="button" onclick="check()" name="Submit"><b>Submit</b></button>
</form>

Upvotes: 0

Mayank Shekhar
Mayank Shekhar

Reputation: 46

Firstly, I would like to understand what is your object after getting the data from REST API.

Secondly, there are mistakes in the html code as well, you don't need to add onclick on the submit button when there you already have a onsubmit on the form element.

Solution, change onsubmit="check(event);"

function check(e) { e.preventDefault() ... } // you can remove the return true

Upvotes: 0

Rajender Verma
Rajender Verma

Reputation: 399

There were some errors in your code as I've checked, please use it like this

<form method="POST" onsubmit="return check();">{% csrf_token %}
    <p><b>Login</b></p>
    <input type="email" id = "email" name="email" placeholder="Email" required>   
    <input type="password" name="password" placeholder="Password" id='new_password' >
    <span id='message'>{{msg}}</span>
    <button type="submit" onclick="check(event)" name="Submit"><b>Submit</b>  </button>
</form>
<script>
    function check(event) {
        event.preventDefault();
        document.getElementById('message').innerHTML = "checking";

        const url = "https://hostname/login";
        const data = {"email" : document.getElementById('email').value,
                    'password' : document.getElementById('new_password').value
                    };
        const other_params = {
            headers : { "content-type" : "application/json; charset=UTF-8"},
            body : data,
            method : "POST",
            mode : "cors"
        };

        fetch(url, other_params)
            .then(function(response) {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error("Could not reach the API: " + response.statusText);
            }
        }).then(function(data) {
            document.getElementById("message").innerHTML = data.encoded;
        }).catch(function(error) {
            document.getElementById("message").innerHTML = error.message;
        });
        return true;
    }
  </script>

Then test by changing your post URL to correct one whether working or not, for more testing use browser inspector tool to see your ajax request.

I've also put it on fiddle for your live testing http://jsfiddle.net/rajender07/xpvt214o/903616/

Thanks

Upvotes: 1

Related Questions