0

I'm using the jQuery validation plugin, which is very impressive. I define some custom validation methods with custom error messages, and all works well. I just write a function that takes the value of an input element, and the element itself, and specify that function in rules for elements with a given name attribute. The function must return true if the element is valid, and false if it is invalid.

But now I need to do a validation that involves an ajax call. I use code like this:

let retval = true;
$.get(`url`, function(data) {
    console.log( "success: ");
    console.log(data);
    retval = true;
}).fail(function(data) {
    console.log( "error: " );
    console.log(data);
    retval = false;
})
return retval;

The idea being to let the result of the ajax call determine whether the validation method returns true or false. But stepping through it in Chrome developer tools, the return statement is never reached. So the .fail() function that sets retval to false has no effect: stepping off the end of the .fail() function goes into jQuery code, and the validation method returns true. How can I get the function containing the ajax call to return a value that reflects the status of the call?

sootsnoot
  • 2,178
  • 3
  • 22
  • 27
  • 1
    https://stackoverflow.com/q/14220321/438992 – Dave Newton Dec 28 '22 at 20:40
  • Thanks, @Dave Newton. But AFAIK, user-defined validation methods for the jQuery Validation plugin are synchronous: so when performing an ajax request inside of one, you need to wait for it to complete before returning the true/false result. I guess the article you cited means I need to either use $.ajax() with {async:false} instead of $.get(), or else insert some sort of promise code before the return from the custom validator function. Although the article is long and detailed, it relies on callbacks doing something visible to the user, not setting variables visible outside the callback. – sootsnoot Dec 28 '22 at 22:48
  • 1
    … Whether or not it’s “visible to the user” is immaterial; the same thing needs to be done either way. You are attempting to use the results of an async call outside the async call. *(Ignoring that jQuery validation results are visible to the user.)* – Dave Newton Dec 28 '22 at 23:10
  • I just meant that all the examples in the jQuery docs seem to use console.log() within the async call rather than propagating values back to the code that initiated the async call. But I think I'm getting it., although my quick fix is just to use $.ajax() with { async: false }. Thanks for the pointer! – sootsnoot Dec 29 '22 at 16:06
  • It is almost **always** an anti-pattern to set async false (and there's almost never a reason to do so). – Dave Newton Dec 29 '22 at 18:24
  • I'm sorry if I'm being thick. But my situation is that I have a validation function that needs to issue an ajax call and return the result of the call. AFAICT, all of the solutions in your referenced answer involve receiving the result in a different function that runs asynchronously from the function initiating the ajax call. So the validation function can (and usually does) return before the function receiving the result completes. My validation function can't return a value until it has seen the result of the ajax call. I don't see how to do that without disabling async. – sootsnoot Dec 30 '22 at 16:22
  • I can write another question with code and log output illustrating the problem when I use the "Let functions accept callbacks" solution from your cited answer, showing that it doesn't work for me. So I guess I must be modeling that solution wrong, but I'll be darned if I can see where I'm deviating from it. It seems to me that the only way the function making the ajax call can see the result of the call is through an outer-scope variable, and I see nothing to suspend execution of the validation function itself until the ajax action completes, only other functions can be triggered. – sootsnoot Dec 30 '22 at 16:33
  • I wrote [another question](https://stackoverflow.com/questions/75215159/jquery-validation-plugin-validation-custom-method-needs-to-return-result-of-aj), and it received a useful answer instead of a scolding. Turns out that in my situation, my choices are either to use async:false, or else forgo a custom validation method in javascript and use the builtin method `remote`, which internally uses asynchronous javascript to perform the validation on a server. – sootsnoot Jan 26 '23 at 17:49
  • And regarding "visible to the user", my point was that the functions specified in an async ajax request either call console.log or make changes to the DOM. What they can't do is reliably change the value of variables in a scope containing a function invoked by an async ajax request. The plugin's builtin `remote` method can use async because it makes changes to the DOM based on the result; but I can't use it in my custom method because I'm not changing the DOM, but constrained to returning a value to my caller. – sootsnoot Jan 26 '23 at 18:03

0 Answers0