0

I posted a question that was marked as duplicate as this got me doing some research into posting return true; inside a nested function. I now understand about asynchronous code but I'm still having big difficulty coding a solution.

The code that was originally causing me problems, which I was using to submit a form inside an on("submit") function, is:

if($('input[name="lat"]').length){
// submit the form after checks have been made
    return true;
} else {
    e.preventDefault();
    geocode_clientside();
    setTimeout(function () {
        return true;
    }, 1000); // in milliseconds
}

After much reading I got to this:

var result = false;
if($('input[name="lat"]').length){
    // submit the form after checks have been made
    result = true;
} else {
    e.preventDefault();
    geocode_clientside();
    setTimeout(function () {
        result = true;
        // console log just to help me with debugging
        console.log('settimeout: ' + result);
    }, 1000); // in milliseconds
}
// console log just to help me with debugging
console.log('end: ' + result);
return result;

This isn't working, obviously, because return result; is returning "false" when input[name="lat"] has no length. I only understood this when I coded my new solution, and it feels like I've run a big circle and come back to the start of my problem. I fully understand now why it's returning false, what I don't understand is the solution that will get me to the end (without returning to the beginning).

I tried something stupid, which was to wrap the return result; in a delay function, which was a disaster.

Can anyone help me here, please?

luke_mclachlan
  • 1,035
  • 1
  • 15
  • 35
  • This is because of `setTimout` function. Why do you use it in the first place? – Artyom Neustroev Mar 30 '15 at 11:11
  • timer runs in a asyc manner so the callback to the timer will be executed only after the value is returned so any changes done to the variable will not be reflected in the returned value – Arun P Johny Mar 30 '15 at 11:11
  • @ArtyomNeustroev It's there to wait for the results from Googles geocoding service. I'm appending hidden lat() and lng() form fields and these take about 500ms before they're visible. If the form submits too fast, they're not being appended in time. – luke_mclachlan Mar 30 '15 at 11:14

1 Answers1

1

Since you want to do a form submit, you can call the form element's submit method directly.

So in the else block you will prevent the default form submission that will prevent the form submission on click. Then in the timer you can call the submit() method if you want to submit the form(It will not call the submit handler)

$('form').submit(function () {
    var form = this;
    if ($('input[name="lat"]').length) {
        // submit the form after checks have been made
        return true;
    } else {
        e.preventDefault();
        geocode_clientside();
        setTimeout(function () {
            form.submit();
        }, 1000); // in milliseconds
    }
})

Note: From your comments you are using geolocation api, so don't depend on a timeout to guess when that will be completed, instead use a callback method to submit the form

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Thanks. I understand the logic of your answer but for some reason form.submit() does not trigger the submission of my form. So I removed the setTimeout function and on form submit I noticed that the geocode_clientside() function is repeating itself over a thousand times until the page crashes. I'll mark your answer as correct because it is, it's just that there is something fundamentally wrong with other parts of my code :-( – luke_mclachlan Mar 30 '15 at 12:20
  • Arun, Thanks for the tip regarding using a callback method, instead of setTimeout(). I have tried to use the code `$.when(geocode_clientside()).then(function(){form.submit();});`. This works great in that the geocode_clientside() function is triggered and works, but form.submit(); isn't being triggered. So what I did was to put an alert inside the then() function but it isn't being triggered. Which leaves me thinking that it's still waiting for a message that the geocode_clientside() function has completed. Am I right in thinking this? Thanks. – luke_mclachlan Mar 30 '15 at 16:59