JavaScript API - Sync Method

JayC

Always Learning
Aug 8, 2013
5,493
1,398
Hey Guys,

How can I call a sync function for ajax url GET, and wait for a result (rather than returning "undefined" or an unfilled PROMISE ?

I have tried so many things and I can't get this function to work properly.

Parent Function:
Code:
checkValidity: function(input) {
        for ( var i = 0; i < this.validityChecks.length; i++ ) {

            var isInvalid = this.validityChecks[i].isInvalid(input);
            if (isInvalid) {
                this.addInvalidity(this.validityChecks[i].invalidityMessage);
            }

            var requirementElement = this.validityChecks[i].element;

            if (requirementElement) {
                if (isInvalid) {
                    requirementElement.classList.add('invalid');
                    requirementElement.classList.remove('valid');
                } else {
                    requirementElement.classList.remove('invalid');
                    requirementElement.classList.add('valid');
                }

            } // end if requirementElement
        } // end for
    }

The line that calls this is the:

Code:
this.validityChecks[i].isInvalid(input)

Which references this predefined block:
Code:
var phoneValidityChecks = [
    {
        isInvalid: function(input) {
            const regex = RegExp(/\d{10}$/);
            return !regex.test(input.value);
        },
        invalidityMessage: 'Please enter a valid phone number',
        element: document.querySelector('label[for="register_phone"] .input-requirements li:nth-child(1)')
    },
    {
        isInvalid: function(input) {
            checkPhoneExists(input.value).then(json => {
                if (!Array.isArray(json['data']) || json['data'].length === 0)
                    return true;
            
                var exists = json['data'][0];

                return exists;
            });
        },
        invalidityMessage: 'Please enter a unique phone number',
        element: document.querySelector('label[for="register_phone"] .input-requirements li:nth-child(2)')
    }
];

So I am trying to call this function "checkPhoneExists" which will do the following:
Code:
async function checkPhoneExists(phone) {
    $.when(checkPhoneNumberAjax(phone)).done(function(result){
        return result;
    });
}

And the Ajax Function:

Code:
async function checkPhoneNumberAjax(phone) {
    var username = 'User';
    var password = 'Pass';
    var url = 'http://127.0.0.1/app/api/api.php';
    
    var postData = {
        "type" : 'GET',
        "action" : 'phone_exists',
        "phone" : phone,
    };
    
    $.ajax({
        url: url,
        type: 'GET',
        dataType: 'json',
        data: postData,
        contentType: 'application/json',
        beforeSend: function(xhr) {
            xhr.setRequestHeader("Authorization", "Basic "+btoa(username+':'+password));
        },
        success: function(resultData){
            return resultData;
        }
    });
    
    await new Promise(resolve => setTimeout(resolve, 3000));
    
    return true;
}

I have tried everything I can think of to STOP RETURNING and WAIT FOR A RESULT!
 

RastaLulz

fight teh power
Staff member
May 3, 2010
3,926
3,921
When asking a question, try and simplify your code down to exactly what you're trying to do (and many times you'll figure out the solution in the process), instead of including a bunch of domain logic.

Anyways, $.when returns a promise, so you'd likely do something like:
Code:
function checkPhoneExists(phone) {
    return $.when(checkPhoneNumberAjax(phone));
}

Then you could reference it like:
Code:
const result = await checkPhoneExists('XXX-XXXX');
 

JayC

Always Learning
Aug 8, 2013
5,493
1,398
When asking a question, try and simplify your code down to exactly what you're trying to do (and many times you'll figure out the solution in the process), instead of including a bunch of domain logic.

Anyways, $.when returns a promise, so you'd likely do something like:
Code:
function checkPhoneExists(phone) {
    return $.when(checkPhoneNumberAjax(phone));
}

Then you could reference it like:
Code:
const result = await checkPhoneExists('XXX-XXXX');
So the same thing happens here too. It returns undefined:

result = undefined
Code:
async function(input) {
    const result = await checkPhoneExists(input.value);
    if (!Array.isArray(result['data']) || result['data'].length === 0)
    return true;

    var exists = result['data'][0];

    return exists;
}

Phone Exists Functions:
Code:
async function checkPhoneExists(phone) {
    return $.when(checkPhoneNumberAjax(phone));
}


async function checkPhoneNumberAjax(phone) {
    var username = 'User';
    var password = 'Pass';
    var url = 'http://127.0.0.1/app/api/api.php';
   
    var postData = {
        "type" : 'GET',
        "action" : 'phone_exists',
        "phone" : phone,
    };
   
    $.ajax({
        url: url,
        type: 'GET',
        dataType: 'json',
        data: postData,
        contentType: 'application/json',
        beforeSend: function(xhr) {
            xhr.setRequestHeader("Authorization", "Basic "+btoa(username+':'+password));
        },
        success: function(resultData){
            return resultData;
        }
    });
}
 

RastaLulz

fight teh power
Staff member
May 3, 2010
3,926
3,921
I'd recommend figuring out how async/await works (and Promises), and if you're still running into an issue, create a . Posting code snippets isn't that helpful, when you could be improperly using async/await elsewhere, resulting in unexpected behvior.

 

JayC

Always Learning
Aug 8, 2013
5,493
1,398
Yeah I am working on recoding this, I see what my issue is.

It is expecting you to use the 'success' method to invoke the behavior you are expecting. So I am going to make an async function to control my message to the display, and hope it works, aha.
Post automatically merged:

Got it working. I recoded the system to use the 'Success' method as recommended by about every article I could find.

Here is the page now updating:

(First: The entry is 10 digits, and unique)
(Second: The entry is 10 digits, already taken)
(Third: The entry is 10 digits, available)

You must be registered for see images attach



Thanks for the help! Here is what I ended up doing:


Added another anonymous function into my class for custom validation:

Here I tell it which index to use for the validation number, and whether it is invalid or valid
Code:
addAsyncInvalidity: function(index, isInvalid){
        this.addInvalidity(this.validityChecks[index].invalidityMessage);
        
        var requirementElement = this.validityChecks[index].element;

        if (requirementElement) {
            if (isInvalid) {
                requirementElement.classList.add('invalid');
                requirementElement.classList.remove('valid');
            } else {
                requirementElement.classList.remove('invalid');
                requirementElement.classList.add('valid');
            }
        }
    }

I used one single function:
Code:
async function checkPhoneNumber(input, index) {
    var username = 'User';
    var password = 'Pass';
    var url = 'http://127.0.0.1/app/api/api.php';
    
    var postData = {
        "type" : 'GET',
        "action" : 'phone_exists',
        "phone" : input.value,
    };
    
    $.ajax({
        url: url,
        type: 'GET',
        dataType: 'json',
        data: postData,
        contentType: 'application/json',
        beforeSend: function(xhr) {
            xhr.setRequestHeader("Authorization", "Basic "+btoa(username+':'+password));
        },
        success: function(resultData){
            if (!Array.isArray(resultData['data']) || resultData['data'].length === 0)
                return true;
        
            var exists = resultData['data'][0];

            input.CustomValidation.addAsyncInvalidity(index, exists);
        }
    });
}

And to call that function for validation:
Code:
isInvalid: async function(input) {
    const regex = RegExp(/\d{10}$/);

    if (!regex.test(input.value))
    return true;

    checkPhoneNumber(input, 1); //0 Based

    return false; //Async function will update later to set the true state of invalid
}
 
Last edited:

Users who are viewing this thread

Top