Skip to content
Advertisement

admin-ajax returning 0 – not submitting form data to db

I’m trying to send form data to a table called attendants. I have the form, the AJAX and query created, but when trying to test (when submitting the form), I see a POST http://localhost/rsvp/wp-admin/admin-ajax.php 400 (Bad Request) error on console.

Unsure what’s causing this as when I run a console.log(ajaxurl); the URL it returns is http://localhost/rsvp/wp-admin/admin-ajax.php which is correct.

Unsure what’s happening here?

EDIT: I’ve recently discovered that http://localhost/rsvp/wp-admin/admin-ajax.php returns 0.

form.php (Folder Path: rsvp > template-parts > parts > form.php) :

<div class="form sectionPadding" id="rsvp-form">
  <form id="rsvpForm" method="post">
    <?php get_template_part('template-parts/snippets/form-step-1'); ?>
    <?php get_template_part('template-parts/snippets/form-step-2'); ?>
  </form>
</div>

<script type="text/javascript">
  var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
</script>

form.js (form.js compiles into theme.min.js. The path to theme.min.js is rsvp > assets > build > js > theme.min.js) :

jQuery('#rsvpForm').on('submit', function(e) {
  e.preventDefault();

  jQuery.ajax({
    action: 'send_to_db',
    dataType: "text",
    type: "post",
    data: $('form').serialize(),
    url: ajaxurl,

    success: function(data) {
      console.log(data);
    },
    error: function() {
      console.log("Error");
    }
  });


});

functions.php

add_action("wp_ajax_send_to_db", "send_to_db");
add_action("wp_ajax_nopriv_send_to_db", "send_to_db");

function send_to_db(){
	if (isset($_POST['submit'])) {

		global $wpdb;

		$first_name = $_POST['fname'];

		$table_name = $wpdb->prefix . "attendants";
		$row_result = $wpdb->query("INSERT INTO $table_name (first_name) VALUES ('$first_name')" );

		if ($row_result == 1){
			echo "submitted";
		} else{
			echo "error";
		}

		die();
	}
}

To summarize, my folder structure is:

rsvp
   assets
      build
         js
            theme.min.js
   template-parts
      parts
         form
            form.php
            form.js
functions.php

Advertisement

Answer

EDIT: I’ve recently discovered that http://localhost/rsvp/wp-admin/admin-ajax.php returns 0.

That’s indeed the expected return value when the request (URL) doesn’t contain the AJAX action name. Additionally, the HTTP response status would also be a 400 Bad Request which basically means “missing action name” or “there’s no callback registered for that action”.

And in your case, it seems that your AJAX script is not sending the AJAX action.

Because in your form.js script, the action parameter should be in the data — and as far as I know, jQuery.ajax() doesn’t have a action property:

jQuery.ajax({
  action: 'send_to_db', // this should be in 'data'
  ...
  data: $('form').serialize(),
  ...
});

So you can do data: $('form').serialize() + '&action=send_to_db' like so:

jQuery.ajax({
  ...
  data: $('form').serialize() + '&action=send_to_db',
  ...
});

That way, WordPress would recognize the AJAX action (via $_REQUEST['action']) and then run the proper AJAX handler / PHP callback, which is send_to_db() in your case.

And you can confirm if your AJAX callback is registered properly by visiting /wp-admin/admin-ajax.php?action=send_to_db — are you still seeing a 0?

Update

  1. If the HTTP response status is no longer 400 (where it should now be 200), then it means your AJAX request is sending an action (send_to_db in your case) and that there’s a PHP callback registered for that AJAX action (wp_ajax_send_to_db / wp_ajax_nopriv_send_to_db).

    But because your callback is only doing something when the POST variable submit is set, then if your AJAX request data doesn’t include that, the response would still be a 0.

    If you want to avoid that, then you can do something like so:

    function send_to_db() {
        if ( isset( $_POST['submit'] ) ) {
            // ... your code here.
            //die();
        } else {
            echo 'Invalid request!';
        }
    
        wp_die(); // It's recommended to always call this to end an AJAX request,
                  // but die() is OK, too.
    }
    

    And with that, when you manually go to /wp-admin/admin-ajax.php?action=send_to_db (i.e. without sending any POST data), you’d see Invalid request! on the page. window.fetch( '/wp-admin/admin-ajax.php?action=send_to_db' ) would even receive that same response.

    So now that the error 400 is gone, you just need to make sure your AJAX request is sending the proper data and that your PHP callback is working (or doing what it needs to do). And on Chrome, you can easily inspect the request and response data, headers, etc. by opening the developer tools and go to the Network → XHR tab and simply click on the relevant request.

  2. Your SQL query is highly insecure and I strongly suggest you to use wpdb::prepare() to prepare the query for safe execution:

    //$row_result = $wpdb->query("INSERT INTO $table_name (first_name) VALUES ('$first_name')" );
    $query = $wpdb->prepare(
        "INSERT INTO $table_name (first_name) VALUES (%s)",
        sanitize_text_field( $first_name )
    );
    $row_result = $wpdb->query( $query );
    

    Alternatively, for inserting a single database row/entry, you can just use wpdb::insert():

    $row_result = $wpdb->insert( $table_name, array(
        'first_name' => sanitize_text_field( $first_name ),
    ) );
    

And I have actually tested your original PHP callback, and it worked, so long as the request data are good. 🙂

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement