0

I have a form on my page. When the user hits the Send button, in the background it also generates a unique_number by calling for a function that generates this number and also checks in the DB that this number doesn't exist; if it does - generates it again, if doesn't - returns this number. However, for some reason when I'm trying to print out this number to the page, or alert it - I'm getting undefined, though the function returns the number. Here's the call for the function:

var unique_num = create_unique_number();
alert(unique_num);
    rest of this function...

And here's the function itself:

function create_unique_number()
{
var num = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;

$.getJSON("inc/API.php", 
{
    command:"is_unique_number_exist",
    unique_num:num
},
    function(result){
        if(result==true){
            create_unique_number();
        }
        else
        {
            return num;
        }
    });
}

I do get the results, if it's true - it generates new number, if false - should return. I tried to alert the num in the else part, and it did Alert the number, but on return - undefined. Why is it happening and how to fix it?

Igal
  • 5,833
  • 20
  • 74
  • 132
  • Only your callback function of getJson returns the num, there is no return in your create_unique_number function. – Florian F. Jun 13 '13 at 08:59
  • 3
    As a side note, it would be faster to have the server side choose a unique number. Less network used, similar amount of work on the server. – Liosan Jun 13 '13 at 09:02
  • wish this site had a "withdraw close vote" option - the recursive part of this function makes the solution quite, umm, interesting... – Alnitak Jun 13 '13 at 09:11
  • @FlorianF. I need it to return the num only if there's no such num in the DB. I can't just return every number. – Igal Jun 13 '13 at 09:41

1 Answers1

1

For a solution using deferred objects, try this:

function create_unique_number()
{
    var num = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;

    return $.getJSON("inc/API.php", {
        command:"is_unique_number_exist",
        unique_num:num
    }).then(function(result) {
        return result ? create_unique_number() : num;
    });
}

This is of course untested as I don't have your API available, but the theory is that if result is true the .then call returns the result of a recursive call back to the same function. If result is false then it returns the chosen number as the (resolved) result of a new promise.

If any AJAX call fails, the loop should break and you can trap that with a .fail call:

create_unique_number().done(function(n) {
    // use your unique number "n" here
    var unique_num = n;
    ...
}).fail(function() {
    // there was an AJAX error
});

// can't use "unique_num" here - execution continues here immediately
// and "unique_num" isn't defined until the above ".done" callback is
// invoked some time later

Note that the recursive call isn't truly recursive - since AJAX is event driven, the original function will already have terminated and cleaned up its stack long before the AJAX .then event fires. The resulting new call to create_unique_number will be at the same "call stack" level as the original call.

Also, as pointed out in the comments, it would actually be far simpler to have the server give you a random number.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Trying to follow your answer, but guess I'm doing it wrong - I'm getting a `[object Object]` in the return now... My API is simple: it calls for a function in the file BusinessLogic.php: `if(is_unique_number_exist($_REQUEST["unique_num"])) echo json_encode(true);else echo json_encode(false);` which selects a raw from the DB where the number exist, if exists - returns True, if doesn't - False: `{$arr = select("SELECT * FROM tbl WHERE unique_num='$num'"); return (count($arr) > 0);}` Not sure how to have the server give me a 6 numbers only random number. PHP gives 13 characters, nums & letters. – Igal Jun 13 '13 at 09:39
  • @Igal is the `[object Object]` the return value of `create_unique_number` (that's what I'd expect) or the value of `n` passed to the `.done` callback per the final code example? – Alnitak Jun 13 '13 at 09:41
  • Yes, it's the return value. – Igal Jun 13 '13 at 09:47
  • @Igal that's normal then - the return value is a "promise", that you then have to pass via ".done" (as above) in a callback function in order to receive the actual number that you want returned. – Alnitak Jun 13 '13 at 10:15
  • I'm not sure how to pass it via `.done`... Sorry, I'm a novice at this. How do I retrieve the number now? And is there really a possibility to create a 6 digits random number on the server side? – Igal Jun 13 '13 at 10:43
  • @Igal look in the code above - the random number is the parameter `n` passed in the `.done` callback. And yes, of course it's possible to create a six digit random number of the server, but that would be a separate question. – Alnitak Jun 13 '13 at 10:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31714/discussion-between-igal-and-alnitak) – Igal Jun 13 '13 at 11:14