Error calling a secondary method via CALLBACK: Uncaught TypeError: Can not read property 'child_name' of undefined

2

With JavaScript (ECMAScript-6), when calling a method via callback , if this method uses another method the following error occurs:

  

Uncaught TypeError: Can not read property 'child_name' of undefined

If the method is called directly it works perfectly. But if it is called via callback does not work. If you do not have a secondary method, it works as well.

How to call callback , a method of a class, and does this method use other methods?

Below is a snippet of code reproducing the error:

class TestOne{
    metodoPrincipal(str_input){
        this.metodoSecundario(str_input);
    }
  
    metodoSecundario(parametro){
        alert("OK: " + parametro);
    }     
}

function chamaViaCallback(callback, msg){
  callback(msg);
}


var test_objeto = new TestOne(); // instancia o objeto

 // funciona chamando diretamente um método secundário
test_objeto.metodoPrincipal('Testando método secundário chamado diretamente!');

// funciona via callback chamando diretamente o método secundário
chamaViaCallback(test_objeto.metodoSecundario, 'método único chamado via callback!');

// não funciona via callback chamando método secundário
chamaViaCallback(test_objeto.metodoPrincipal, 'método secundário chamado via callback!');
    
asked by anonymous 12.10.2016 / 02:33

3 answers

3

This problem occurs because the metodoPrincipal function loses the object reference.

One way to resolve this is to pass the object through bind :

chamaViaCallback(test_objeto.metodoPrincipal.bind(test_objeto), 'Foo');

Another alternative with an arrow function ( Arrow function ):

chamaViaCallback( msg => test_objeto.metodoPrincipal(msg), 'Bar');

If you prefer to call the arrow function without arguments and pass the message directly:

chamaViaCallback( () => { test_objeto.metodoPrincipal('Baz'); } );

Example:

class TestOne{
    metodoPrincipal(str_input){
        this.metodoSecundario(str_input);
    }
  
    metodoSecundario(parametro){
        console.log("OK: " + parametro);
    }     
}

function chamaViaCallback(callback, msg){
  callback(msg);
}

var test_objeto = new TestOne(); // instancia o objeto

chamaViaCallback( test_objeto.metodoPrincipal.bind(test_objeto), 'Foo' );
chamaViaCallback( msg => test_objeto.metodoPrincipal(msg), 'Bar' );
chamaViaCallback( () => { test_objeto.metodoPrincipal('Baz'); } );
    
12.10.2016 / 04:02
2

When you pass test_objeto.metodoPrincipal to the callback the function of the object is called, however it will not be able to call the function metodoSecundario because you did not pass the object, / p>

So the object (the variable this ) is not defined.

One solution is to pass object and the function name (such as a string ) to callback .

Example, following your code:

function chamaMetodoViaCallback(obj, method, msg){
    obj[method](msg);
}

chamaMetodoViaCallback(test_objeto, "metodoPrincipal", 'método secundário chamado via callback!');
    
12.10.2016 / 03:10
2
  

How to callback a method of a class, and does this method use other methods?

If you intend to reference test_objeto.metodoPrincipal without passing test_objeto to chamaViaCallback , use the Function#bind(instância, argumentos) :

test_objeto.metodoPrincipal.bind(test_objeto)

Function#bind returns the same function, covered by instance and predefined arguments.

    
12.10.2016 / 11:42