0

I'm attempting to issue the following POST request to an API via a form and a submit button.

EDIT: I'm sorry folks, this isn't my morning. This is what the POST request should look like:

$.ajax({
  type: "POST",
  url: "/api/v1/users/",
  data:{
    user: {
      fname: "Test",
      lname: "Johnson",
      password: "passw0rd",
      email: "test2@johnson.com"
    }
  }
})

Here is my html:

<div class="row">
        <div class="three columns">
          <label for="emailInput">email</label>
          <input type="text" id="emailInput">
        </div>
          <div class="three columns">
          <label for="passwordInput">password</label>
          <input type="text" id="passwordInput">
          </div>
        </div>
        <div class="row">
          <div class="four columns">
           <input class="button-primary" type="submit" value="Submit">
          </div>
        </div>

Here is my JavaScript:

email = '';
  password = '';
  firstName = '';
  lastName = '';
$(function() {
  $('.button-primary').click(function(event) {
    var email = $('#emailInput').val();
    var password = $('#passwordInput').val();
    var firstName = $('#fnameInput').val();
    var lastName = $('#lnameInput').val();
    $.post( 'http://<MY-DYNO>.herokuapp.com/api/v1/users/', { fname: firstName,
      lname: lastName,
      password: password,
      email: email,
      success: function(response) {
        $('#registerStatus').text('Successfully registered');
        console.log(response);
      }
    });
  });

This is obviously not the best way to go about this, but I'm in the process of learning AJAX. If anyone can provide some guidance that would be great, I've been struggling with this for many hours.

EDIT: I apologize, I did not describe the exact issue I was having. After I hit submit, the div is populated with Successfully Registered, but the data is not being properly submitted to the server, it is passing undefined.

damianesteban
  • 1,603
  • 1
  • 19
  • 36
  • 3
    What is the actual issue you are having? – Michael Coxon Apr 20 '15 at 15:32
  • 1
    why do you say "This is obviously not the best way to go about this"... to do a post with JQuery, i'm sure is the best way – lem2802 Apr 20 '15 at 15:32
  • Is the page containing the form served by art-share.herokuapp.com? If not, you won't have access to the response, as per the [Same-origin policy](http://en.wikipedia.org/wiki/Same-origin_policy). – instanceofnull Apr 20 '15 at 15:33
  • Alternatively, you may be interested in this very handy jQuery plugin: http://malsup.com/jquery/form/ – instanceofnull Apr 20 '15 at 15:34
  • Avoid to share real url in you example :) – martinezjc Apr 20 '15 at 16:01
  • 1
    @martinezjc Yes, you are absolutely right – damianesteban Apr 20 '15 at 16:23
  • but that $.post() don't send a "data" querystring, but sends (in your case) 4 querystrings: fname, lname, password and email, so you must retrieve the values this way (for example in a generic handler .ashx or even if it was a page .aspx): string lname = context.Request.QueryString["lname"] as string; – AiApaec Apr 20 '15 at 16:26

2 Answers2

2

In my first observation, I found that your JS code is not correct. it should be:

$(function () {
    $('.button-primary').click(function (event) {
        var email = $('#emailInput').val();
        var password = $('#passwordInput').val();
        var firstName = $('#fnameInput').val();
        var lastName = $('#lnameInput').val();
        $.post('http://art-share.herokuapp.com/api/v1/users/', {
            fname: firstName,
            lname: lastName,
            password: password,
            email: email
        }, //<-- Note closing json
        function (response) { // <-- Note one change here
            $('#registerStatus').text('Successfully registered');
            console.log(response);
        });
    });
});

Documentation: https://api.jquery.com/jquery.post/

Apul Gupta
  • 3,044
  • 3
  • 22
  • 30
  • actually since `$.post` is just a wrapper around `$.ajax` (minus some other trivial changes), you can pass in a success block with the key `success` to the hashmap provided as a singular argument to `$.post`. – David Zorychta Apr 20 '15 at 16:07
  • The result of this is the following: ```Object {status: 400, result: Object}result: Objectpassword: Array[1]0: "can't be blank"length: 1__proto__: Array[0]__proto__: Objectstatus: 400__proto__: Object``` – damianesteban Apr 20 '15 at 16:11
  • @damianesteban it sounds like either `var password = $('#passwordInput').val();` isn't working, or that you're sending the wrong property name when you send the password. – David Zorychta Apr 20 '15 at 16:15
  • I would agree with you, but I can't see where the issue could possibly be. – damianesteban Apr 20 '15 at 16:37
  • @damianesteban can you please share a working code example so that we can get clear idea. – Apul Gupta Apr 21 '15 at 06:54
  • The issue is that I am not able to enable CORS. – damianesteban Apr 21 '15 at 15:39
1

You haven't actually said what the problem is in your question (is the form not submitting?) so this is going to be a very generalized answer on how to debug javascript problems such as this.

First, you should insert calls to console.log to see what's going on better:

$(function() {
  console.log('DOCUMENT READY'); // <<<<<<<<< ADD LOG HERE
  $('.button-primary').click(function(event) {
    console.log('CLICK EVENT WORKED'); // <<<<<<<<< ADD LOG HERE
    var email = $('#emailInput').val();
    var password = $('#passwordInput').val();
    var firstName = $('#fnameInput').val();
    var lastName = $('#lnameInput').val();
    console.log('SENDING', email, password, firstname, lastname); // <<<<<<<<< ADD LOG HERE
    $.post( 'http://<MY-DYNO>.herokuapp.com/api/v1/users/', { fname: firstName,
      lname: lastName,
      password: password,
      email: email,
      success: function(response) {
        $('#registerStatus').text('Successfully registered');
        console.log(response);
      }
   }).done(function() { console.log('your ajax call worked'); }) // <<<<<<<<< ADD LOG HERE
   .fail(function() { console.log('something went wrong'); }) // <<<<<<<<< ADD LOG HERE
   .always(function() { console.log('something went really wrong'); }); // <<<<<<<<< ADD LOG HERE
  });
});

Now run this and see which logs get written (in Chrome go to right click webpage > inspect element > console) - you'll now know how far your code gets before it stops working.

Another useful tool for debugging ajax requests (assuming again you're using Chrome) is the Network tab within the debugging console. On your webpage right click > inspect element and choose the Network tab at the top. You'll see something like this:

enter image description here

Make sure the circle in the top left is red and if not, press it. Now Chrome is monitoring web requests (including ajax requests) for your current webpage, and you can now submit your form and make sure that a new record is added to the top of this list of requests. You can then click on the request and see exactly to which URL it submitted to, what data was submitted, and what the response was.

You should also be using the Console tab at the top as well. If your request was blocked because you're on domainA.com and did an AJAX request to domainB.com (this is illegal - you can't do AJAX cross domain without a CORS technique such as JSONP or without explicit CORS headers on the server) then such an error will show up in the console tab:

enter image description here (note: the requests in the above image were blocked by adblock - but you get the picture, this tab will tell you if/why AJAX requests failed)

You should now know exactly what was preventing your AJAX request from working properly. If none of the console.log calls ran then the problem is with your inclusion of jQuery, or your event listener on your button. If the 'SENDING' console.log right before the AJAX call doesn't work then you know the problem has to do with extracting data from DOM elements on your webpage (or whatever is between the previous call to console.log and this one). If all these console.log calls work then you should inspect the Network tab and continue to look in the Console tab in Chrome for more clues as to what went wrong, as at this point the problem is likely to do with you violating the same origin policy and thus having to do a technique like this to get around it, or the problem could just be with your server and you may want to consider debugging options there.

edit: in accordance with your edit where you've said the server isn't receiving what you're sending it, to confirm that this is actually true you should first check the Console tab to see if the values you're sending out were printed (recall that we added a console.log call to print out firstName, lastName, etc). If you don't see those being printed out on your Console tab then the problem has to do with your lines such as var firstName = $('#fnameInput').val(); being incorrect.

If you do see the right values for email, password, firstName and lastName being printed on the Console tab, you then need to perform the actions outlined above where you record the request from the Network tab in Chrome (when you click on the request in the Network tab, in the 'Request Headers' or 'Form Data' section you should confirm that the variables you are sending are either there or not there). If you do see the variables being sent as part of the request then you should also make sure that you're submitting the right kind of request (POST and not GET). You should also confirm with your server code that you are sending the right names for variables ("email" not "Email"). If all this matches up then it's possible that the problem is with the server application.

Community
  • 1
  • 1
David Zorychta
  • 13,039
  • 6
  • 45
  • 81
  • Thank you for your detailed answer. This is the server response: ```XMLHttpRequest cannot load http://.herokuapp.com/api/v1/users/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 404.``` – damianesteban Apr 20 '15 at 16:23
  • ```main.js:87 SENDING bobby@bobby123.com bobby1234 bob bobby 2015-04-20 12:30:08.976 main.js:94 undefined 2015-04-20 12:30:09.302 jquery-2.1.3.min.js:4 POST http://.herokuapp.com/api/v1/users/ n.ajaxTransport.k.cors.a.crossDomain.send @ jquery-2.1.3.min.js:4n.extend.ajax @ jquery-2.1.3.min.js:4n.each.n.(anonymous function) @ jquery-2.1.3.min.js:4(anonymous function) @ main.js:88n.event.dispatch @ jquery-2.1.3.min.js:3n.event.add.r.handle @ jquery-2.1.3.min.js:3 2015-04-20 12:30:09.303 main.js:97 something went wrong 2015-04-20 12:30:09.303 main.js:98 something went really wrong``` – damianesteban Apr 20 '15 at 16:32
  • So it would appear the server is not allowing me to submit a POST request via a form? – damianesteban Apr 20 '15 at 16:33
  • The server isn't allowing you to send such a request because of something called the same origin policy. On the web with some requests (such as AJAX requests) you aren't allowed to perform these requests if they are to another domain. Since localhost != you.herokuapp.com, you are not allowed to do the request. If you have access to the server code you can try enabling cross origin requests (google search "enable CORS in PHP/rails/nodejs/etc). – David Zorychta Apr 20 '15 at 16:36
  • Thank you, I do have access to the server code. I will try that. – damianesteban Apr 20 '15 at 16:39