Rob Hughes Rob Hughes - 6 months ago 25
Ajax Question

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.

Answer

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.

Comments