A. Vreeswijk
A. Vreeswijk

Reputation: 954

JavaScript Faster way to ask for null value

I have a question. I created the following functions:

function checkGender(canidate, callback) {

    var query = "SELECT a.* FROM (SELECT Id AS GebruikerId, TIMESTAMPDIFF(year, profiel_Geboortedatum, NOW()) AS Leeftijd FROM " + 
    "gebruikers WHERE Id = " + canidate.MedereizigerId + ") a INNER JOIN gebruikers ON gebruikers.Id = " + canidate.GebruikerId + " WHERE a.Leeftijd >= gebruikers.medereiziger_MinLeeftijd AND " + 
    "a.Leeftijd <= gebruikers.medereiziger_MaxLeeftijd GROUP BY a.GebruikerId;";
    
    FYSCloud.API.queryDatabase(query).done(function (data) {
    
        if (data.length == 1) {
            callback(data);
        }
        else {
            callback(null);
        }
    
    }).fail(function (reason) {
        console.log(reason);
        callback(null);
    });
}



function checkAge(canidate, callback) {

    var query = "SELECT a.* FROM (SELECT Id AS GebruikerId, TIMESTAMPDIFF(year, profiel_Geboortedatum, NOW()) AS Leeftijd FROM " + 
    "gebruikers WHERE Id = " + canidate.MedereizigerId + ") a INNER JOIN gebruikers ON gebruikers.Id = " + canidate.GebruikerId + " WHERE a.Leeftijd >= gebruikers.medereiziger_MinLeeftijd AND " + 
    "a.Leeftijd <= gebruikers.medereiziger_MaxLeeftijd GROUP BY a.GebruikerId;";
    
    FYSCloud.API.queryDatabase(query).done(function (data) {
    
        if (data.length == 1) {
            callback(data);
        }
        else {
            callback(null);
        }
    
    }).fail(function (reason) {
        console.log(reason);
        callback(null);
    });
}

[...]

Now the queries are working like a charm but I am using the following code to call these functions:

for(var i=0; i<data.length; i++) {
        
    // CHECK GESLACHT
    checkGender(data[i], function(genderData) {
        if(genderData != null) {
            
            // CHECK LEEFTIJD
            checkAge(data[i], function(ageData) {
                if(ageData != null) {
                
                    // CHECK BUDGET
                    checkBudget(data[i], function(budgetData) {
                        if(budgetData != null) {
            
                            // CHECK VAKANTIELAND
                            checkDestinationCountries(data[i], function(destinationCountryData) {
                                if(destinationCountryData != null) {
                
                                    // CHECK GESPROKEN TALEN
                                    checkSpokenLanguages(data[i], function(spokenLanguagesData) {
                                        if(spokenLanguagesData != null) {
                                            
                                        }
                                    });
                                }
                            });
                        }
                    });
                }
            });
        }
    });
}

What I am doing here is waiting for the function to finish and then continue with the next one, but only if the result of the function didn't return null. Now this takes up a lot of lines and tabs, so I was wondering if there was a beter way to ask everytime for a null value?

Please let me know, just out of curiosity

Upvotes: 0

Views: 170

Answers (2)

Todd Skelton
Todd Skelton

Reputation: 7239

You can use the && operator to check for a falsy value (null, 0, false, undefined, etc.) before executing a function.

value && functionCall(value)

That might make it a bit cleaner.

checkGender(data[i], genderData => genderData &&
    checkAge(data[i], ageData => ageData &&
        checkBudget(data[i], budgetData => budgetData &&
            checkDestinationCountries(data[i], destinationCountryData => destinationCountryData &&
                checkSpokenLanguages(data[i], spokenLanguagesData => spokenLanguagesData && console.log("It Works"))))))

Upvotes: 0

Leo
Leo

Reputation: 2360

You can change your function to a Promise based result, instead of calling callbacks use resolve and reject, like this:

function checkAge(canidate) {

    // create a new Promise and return it
    return new Promise((resolve, reject) => {
        var query = "SELECT a.* FROM (SELECT Id AS GebruikerId, TIMESTAMPDIFF(year, profiel_Geboortedatum, NOW()) AS Leeftijd FROM " + 
        "gebruikers WHERE Id = " + canidate.MedereizigerId + ") a INNER JOIN gebruikers ON gebruikers.Id = " + canidate.GebruikerId + " WHERE a.Leeftijd >= gebruikers.medereiziger_MinLeeftijd AND " + 
        "a.Leeftijd <= gebruikers.medereiziger_MaxLeeftijd GROUP BY a.GebruikerId;";
        
        FYSCloud.API.queryDatabase(query).done(function (data) {
            if (data.length == 1) {
                resolve(data); // when successful, resolve with data
            }
            else {
                reject('no data found'); // any error, call reject()
            }
        
        }).fail(function (reason) {
            console.log(reason);
            reject(reason); // any error, call reject()
        });
    });
}

With this, you can use async/await feature to write a generic validation method with all others validation functions, because any call to reject will throw a exception:

async function checkData(data) {
    try {
        const genderData = await checkGender(data);
        const ageData = await checkAge(data);
        const budgetData = await checkBudget(data);
        const destinationCountryData = await checkDestinationCountries(data);
    } catch (e) {
        // some validation failed
    }
}

Upvotes: 3

Related Questions