Adam Bronfin
Adam Bronfin

Reputation: 1279

Rails form submit via ajax post not calling success or error callback function

I have a rails 4 application where I have a contact form which I post to my rails endpoint to process it, send out an email, and then send back json with a redirect url to the client.

my html form is like so:

<form name="contact_form" action="/contact" class="forms" >
            <fieldset>
              <ol>
                <li class="form-row text-input-row name-field">
                  <input type="text" name="name" class="text-input defaultText required" title="Name (Required)"/>
                </li>
                <li class="form-row text-input-row email-field">
                  <input type="text" name="email" class="text-input defaultText required email" title="Email (Required)"/>
                </li>
                <li class="form-row text-input-row subject-field">
                  <input type="text" name="subject" class="text-input defaultText" title="Subject"/>
                </li>
                <li class="form-row text-area-row">
                  <textarea name="message" class="text-area required"></textarea>
                </li>
                <li class="form-row hidden-row">
                  <input type="hidden" name="hidden" value="" />
                </li>
                <li class="button-row">
                  <input onclick="contact_email()" type="submit" value="Submit" name="submit" class="btn btn-submit bm0" />
                </li>
              </ol>
              <input type="hidden" name="v_error" id="v-error" value="Required" />
              <input type="hidden" name="v_email" id="v-email" value="Enter a valid email" />
            </fieldset>
          </form>

My javascript function is:

function contact_email(){
    form = $('form')
    form_data = document.forms.contact_form;

    $.ajax({
        type: "POST",
        url: form.attr('action'),
        data: form_data,
        dataType: "JSON",
        async: false,
        success: function(data) {
            alert(data);
            window.location = data.redirect_url;
        },
        error: function(xhr, status) {
            alert(status);
        }
    });
}

(I have tried with an without async: false many times, as well as return false; at the end of function without it working)

and my rails endpoint to process the POST

def contact_email
    UserMailer.contact_email(params).deliver
    flash[:message] = "Thank you for contacting us! We'll be in touch shortly"
    res = {:redirect_url => root_url}    
    render :json => JSON.generate(res)
end

After my javascript fires, the contact_email endpoint is hit, and it sends out the JSON response perfectly fine.

The response is

{"redirect_url":"http://localhost:3000/"}

Yet neither my ajax success or error callback is ever executed.

Why is this?

EDIT:

This may not be relevant, but I do see one console error in browser dev tools

Uncaught TypeError: Illegal invocation

for jquery-1.11.1.js

Upvotes: 1

Views: 1156

Answers (2)

mccannf
mccannf

Reputation: 16659

As you are getting Uncaught TypeError: Illegal invocation in the console, usually this means you are trying to pass a HTML element via the data attribute, which JQuery does not like. If you use serialize it converts the form into a string containing a series of url-encoded name-value pairs which is then readily passed via ajax.

It seems in this case that the ajax call actually completed the POST request and then subsequently fails on the Illegal invocation, which means the subsequent success or error callbacks do not get executed.

So - just serialize your form like so:

function contact_email(){
    form = $('form')

    $.ajax({
        type: "POST",
        url: form.attr('action'),
        data: form.serialize(),
        dataType: "JSON",
        async: false,
        success: function(data) {
            alert(data);
            window.location = data.redirect_url;
        },
        error: function(xhr, status) {
            alert(status);
        }
    });
}

Upvotes: 1

Hemali
Hemali

Reputation: 465

Set form as remote:true.

this says that submit the form using ajax rather than following forms action.

Upvotes: 0

Related Questions