Rob Hughes
Rob Hughes

Reputation: 906

Access JSON data using jquery

I am trying to validate the uniqueness of an email address in my form using ajax but I don't know how to access the JSON data using jquery.

So far when a user enters an email address (currently on keyup ) the input gets sent to the controller and JSON data gets returned with a variable {"email_exists":true} or {"email_exists":false} depending on if the email address has been previously saved to the database or not. This works correctly.

I am using jquery to validate other form functions (email validation, field presence) on form submit, and dynamically showing errors depending on the problem.

My issue is that I have no idea how to access the returned JSON data using jquery. I am also struggling to access it from with erb, <%= p params[:email_exists] %> shows nothing. I am new to JSON and any help would be appreciated, thanks.

EDIT: This is how I'm validating the email address.

new.html.erb

$("#comingsoon_email").on('change keyup paste',function(){
        console.log("change?");
    $.post('/checkemail?email='+$("#comingsoon_email").val(),function(data){

routes.rb

post '/checkemail', to: 'comingsoons#emailcheck'

comingsoons_controller.rb

def emailcheck
  @comingsoon = Comingsoon.search(params[:email])
  respond_to do |format|
    format.json {render :json => {email_exists: @comingsoon.present?}}
  end
end

comingsoon.rb

def self.search(email)
        if email
            where('email = ?',email).first
        end

    end

JSON returns

{"email_exists":true} or {"email_exists":false} depending on if the email address has been previously saved to the database or not.

I want to display an error message via jquery if the email address has been taken.

Upvotes: 0

Views: 73

Answers (1)

Dave Newton
Dave Newton

Reputation: 160191

In the function you pass to $.post you have data. That's JSON.

data.email_exists is the value of that JSON data, roughly:

$.post('/checkemail?email='+$("#comingsoon_email").val(), function(data) {
  console.log(data.email_exists);
});

Vaguely related, you'll probably want to:

  1. Clean the email field value
  2. Create the URL outside of the function call to make it read easier
  3. You can use $(this).val() instead of re-referencing the element, although this is purely readability, not functionality
  4. Have the callback be an external function instead of an inline, anonymous function–again for readability, but also testability

So it'd end up looking more like:

function processEmailValidation(data) {
  var emailExists = data.email_exists;
  console.log(emailExists);
  // Do actual stuff
}

The keyup/change/paste handler would look more like:

var url = '/checkemail?email=' + $(this).val();
$.post(url, processEmailValidation);

You should handle Ajax failure gracefully as well, which I haven't reflected here.

Personally I'd also extract the keyup/change/paste handler as well, and separate out the DOM-specific code from the handler code, again for testability. But that's a separate issue.

Upvotes: 2

Related Questions