1

I've got a rather large plugin that I am currently writing in jQuery which is using a lot of internal functions that can accept varying arguments depending on the function.

I caught myself constantly writing the following in every function to stop the code from running if an argument hasn't been supplied or isn't valid:

add : function(args) { 
    if (args===undefined) return;
    // function code;
},...

I was hoping that in a DRY type of sense it would be a good idea to write a little internal helper function that would do this for me.

Is this actually a good idea and most importantly what is the best/secure way to check for a varied range of acceptable arguments?

There are a lot of functions with multiple arguments in this plugin, for example:

load : function( filename , path , excludeFromRandom , callback ) {}

where filename is a string, path is a string, excludeFromRandom is a boolean and callback can be a function or a string.

What is a good way to check for the existence and validity of these types of arguments without rewriting the same code over and over?

Any suggestions and ideas would be great.

Thanks for reading.

1 Answer 1

2

It depends to what extent you want to do this. In idea would be to create a validation function which takes a argument -> rule mapping. E.g.:

function foo(somestring, somenumber) {

    var rules = {
       'somestring': Validator.rules.isString,
       'somenumber': Validator.rules.inRange(5,10);
    };


} 

Validator would contain the basic logic and some helper functions (rules):

var Validator = {
    valid: function(args, rules) {
        for(var name in rules) {
            if(!rules[name](args[name])) {
                return false;
            }
        }
        return true;
    },
    rules: {
        isString: function(arg) {
            return (typeof arg === 'string');
        },
        inRange: function(x,y) {
            return function(arg) {
                return !isNaN(+arg) && x <= arg && arg <= y;
            }
        }
    }
}

This is just a sketch, it certainly can be extended (like accepting multiple rules per argument), but it should give you some idea.

That said, you don't have to check every argument. Provide decent documentation. If people use your plugin in a wrong way, i.e. passing wrong argument types, then your code will throw an error anyway.

Update:

If want to do this very often, then a good idea is to write a wrapper function and you just pass the function and the rules to it:

function ensure(func, rules, context) {
    context = context || this;
    return function() {
        if(Validator.valid(arguments, rules)) {
            return func.apply(context, arguments);
        }
        return null; // or throw error, whatever you want
    }
}

Then you can define your function normally as:

var foo = function(somestring, somenumber) {
    // ...
};

and just add validation to it:

var rules = {...};
foo = ensure(foo, rules);

You could even consider to make ensure accept a callback which gets called on error or success of the function, instead of returning a value. There are a lot of possibilities.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I will give this a go and see if I can set this up to my liking. Would there be any way to directly pass in the args into the function such as args.isValid() which could then return true or false?
@Jannis: If you mean arguments.isValid(), then no.
Yep, I was hoping that would work since it would make it such a nice readable statement boolean.isValid(); but I guess just setting up and object for type and rule will work too. Thanks.
Actually, one more question in regards to your answer. Is there any way to 'stop' foo() from within the valid() function? Like return; would while inside foo()? Without wrapping it in an if statement I mean.
@Jannis: I'm afraid I also have to say no here. But I will update mu answer to show something else... just a second.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.