Darcbar
Darcbar

Reputation: 888

Can't access javascript parent function in attempted validation function - maybe closure needed

I'm trying to write a simple function which would validate an input but I'm having trouble accessing a parent object function.

I think the problem is that I need a closure but as I'm quite new to js and I'm having difficulty getting my head around closures I thought maybe seeing it in action in my code might help, if it is indeed the problem.

function validate(value, validator){

  if(validator == 'login_cred'){
    testName(value);
  }

  var test = {
    minLength: function (val, length) {
      return val.length >= length;
    }
  }

  function testName(value){
    if(!test.minLength(value, 5)){
      console.log('more chars please...');      
    }      
  }

}

//call
validate("str", 'login_cred');

When I call the function I get test is undefined error.

Is this a case of needing a closure?.. if so how would a closure work best in the above code?

Upvotes: 0

Views: 107

Answers (2)

Bergi
Bergi

Reputation: 664307

No, the variable is in scope and you don't need an extra closure. Only you assign to the var test after you call testName which uses it. Move the test object (and the testName declaration) to the top:

function validate(value, validator) {
    function testName(value) {
        if (!test.minLength(value, 5)) {
            console.log('more chars please...');
        }
    }
    var test = {
        minLength: function (val, length) {
            return val.length >= length;
        }
    }
    if (validator == 'login_cred') {
        testName(value);
    }
}
//call
validate("str", 'login_cred');

Of course, unless you have some more code in that function, you just should reduce it to

function validate(value, validator) {
    if (validator == 'login_cred' && value.length < 5)
        console.log('more chars please...');
}

:-)

Upvotes: 1

Jacob T. Nielsen
Jacob T. Nielsen

Reputation: 2978

The function testName gets hoisted. Because of this you code actually looks like this.

function validate(value, validator){

  function testName(value){
    if(!test.minLength(value, 5)){
      console.log('more chars please...');      
    }      
  }

  if(validator == 'login_cred'){
    testName(value);
  }

  var test = {
    minLength: function (val, length) {
      return val.length >= length;
    }
  }

}

//call
validate("str", 'login_cred');

as you can see test has not been declared yet when it is called, and simple placing testName at the bottom does not change this. Simply change your code to this and it will work.

function validate(value, validator){

 var test = {
    minLength: function (val, length) {
      return val.length >= length;
    }
  }

  if(validator == 'login_cred'){
    testName(value);
  }

  function testName(value){
    if(!test.minLength(value, 5)){
      console.log('more chars please...');      
    }      
  }

}

//call
validate("str", 'login_cred');

Upvotes: 1

Related Questions