0

I have the following code:

var bduplicate;
bduplicate = false;
bduplicate = check_for_duplicate_rule().done(function (result) {
    console.log("result from check for duplicate" + result);
    if(result == 'true') {
        $('#validation_error').html("A similar rule already exists");
        return result;
    }
});

console.log(bduplicate);

if(bduplicate.success == 'true') {
    console.log('im exiting');
    return false; //exit this function
}

And here's the definition of the async method itself:

function check_for_duplicate_rule() {
    var parameters = {
        num: $('#num').val(),
        condition: $('#condition').val(),
        cdidnumber: $('#cdidnumber').val()
    }

    return $.getJSON(
        url = aURLdefinedsomewhere,
        parameters,
        function (data) {
            //if (data=='true') {                               
            //$('#validation_error').html("A similar rule already exists");     
            //}
        } //end data
    ); //end getJSON        
}

Problem:

The system never enters into the IF statement that prints to the console "im entering". But it does correctly change the text of the validation_error element. And it prints the following in the console: result from check for duplicate:true ". This leads me to believe that the way I'm testing for the results stored in bduplicate is incorrect.

What I've tried so far:

I included the following line in the code:

console.log(bduplicate);

to see what I'm getting back. The console prints the contents of the object and includes a bunch of different properties. There's one called "responseText" property, it says responseText: ""true"↵" Could this be the problem? Although, if it is, it doesn't explain why the test to set the validation error element passes.

In case it helps, the server is the data for the ajax call like so:

 return json.encode(true)

Questions:

  1. In addition to trying to figure out why I can't get the code to display the results from the "console.log('im exiting')" command, I'm also wondering if the way I'm returning the json data is correct?
    I read somewhere that technically, it should look like this:

    return json.encode('success: true') If this is correct, how would I test for true in the front end?

  2. Can anyone point me to some documentation on the object that's returned by the .done() method? I've been searching the jquery API but haven't found anything yet. I'm probably not searching with the right key words.

Thanks.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
mark li
  • 347
  • 1
  • 7
  • 22
  • 1
    bduplicate is a deferred object, the value of success isn't assigned until the promise is resolved. You'll need to check for "bduplicate.success" within the scope of the "done" function. More info: http://api.jquery.com/deferred.done/ – rtimoshenko Jul 29 '13 at 17:55
  • @FabrícioMatté for the first part of the question, I'd vote dupe but not the second part. – Matt Lo Jul 29 '13 at 18:04
  • @MattLo Right, also the `json.encode` (in the Q1) is most likely wrong but I can't tell as the OP didn't mention which server language is being used. – Fabrício Matté Jul 29 '13 at 18:17

3 Answers3

1

Answer to Question 1: The call is asynchronous, meaning you can have additional processes prior to the request finishing. console.log(bduplicate); is a little misleading because in Chrome it'll show you the updated object but in reality is doesn't update until the call is finished. Any code outside the callback is going to be executed BEFORE your call is done. You'll need to figure out how to pass your data appropriately within the callback handler.

Answer to Question 2: jQuery.ajax > jqXHR.done is part of the promises/deferred paradigm (http://api.jquery.com/deferred.done/). The object comes from a private instance of jqXHR http://api.jquery.com/jQuery.ajax/#jqXHR.

Matt Lo
  • 5,442
  • 1
  • 21
  • 21
  • Matt, so are you saying that the reason why the validation error is being set correctly is because for some reason, eventhough the result hasn't actually been received from the server, the result is evaluating to true and therefore, changing the html for that element? – mark li Jul 29 '13 at 18:13
  • 1
    @markli Before considering what happens to the UI, you'll want to really understand the async nature. If you need a sequential process (AJAX then UI manipulation), just invoke a UI manipulation method in the callback and not outside the `done` method. Theres already a strongly vetted post on HTTP ASYNC (specifically jQuery) at http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call (mentioned by @FabrícioMatté) – Matt Lo Jul 29 '13 at 18:22
  • thanks Matt Lo! That last comment was very very helpful! – mark li Jul 29 '13 at 18:28
1

jQuery AJAX methods, like $.getJSON, return a deferred object. These let you attach callbacks that get triggered when the AJAX call is done.

.done() is attaching a callback. With AJAX, it's asynchronous. That means it happens in the background. You cannot return from an asynchronous method. Your return result; does absolutely nothing.

You need to do all actions relating to the returned data inside the callback.

Here are the docs for jQuery's deferred object: http://api.jquery.com/category/deferred-object/

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • is there a way i can exit the function from within the callback? the code you see that contains the .done() method is inside a .live("click", function(){} and what I need to do is if the ajax method returns true, I just want to exit the .click event handler. – mark li Jul 29 '13 at 18:09
  • 1
    @markli: No, you can't do that. How AJAX works is that it runs in the background. The AJAX request is fired, then the rest of the click handler runs. Chances are the `.done` will be called after the `click` event has already finished. So, like I said, you need to do *all* actions that use the result *inside* the callback. – gen_Eric Jul 29 '13 at 18:13
  • so perhaps I should not be using ajax to do form validation... because i need to know if something is true/false before proceeding on to the next step / validation point. in the example I've posted above, if the ajax call returns true, then i don't populate a part of the form. whereas if it is false, i do populate it. Thanks btw for the clear explanation. i'm just a newbie so I appreciate your clear and descriptive answers. – mark li Jul 29 '13 at 18:18
  • You can use AJAX for form validation. What you can do is just disallow the user from continuing or changing the value until the AJAX call is done. – gen_Eric Jul 29 '13 at 18:20
  • thanks Rocket. I'll do some research on that. – mark li Jul 29 '13 at 18:28
1

To answer your first question, install Chromium, hit your page, then Ctrl-Shift-i to bring up the debugger. Then hit sources tab, find your js file and set a break point. When your breakpoint is hit, inspect your object. Chromium will gladly expand your objects.

ilan berci
  • 3,883
  • 1
  • 16
  • 21