Passing class method as callback to another class in javascript

All we need is an easy explanation of the problem, so here it is.

I am trying to create a pop up menu (via a class) called from another class. After these inputs are filled in I want the input data to be processed by the object from which the pop up menu was initiated.

My thought process created the following code (simplified ofc):

class foo{
    constructor(){
        this.prroperty = 'yes';
    }

    eventMethod(){
        let eventForm = new bar();
        eventForm.fire(this.endMethod);
    }

    endMethod(values){
        // console.log(this);
        console.log(values + this.prroperty);
    }
}

class bar{
    constructor(){
        this.property = 'no';
    }

    fire(callback){
        let value = 'message';
        callback(value);
    }
}

let object = new foo();
object.eventMethod();

this doesn’t work obviously because "this" now no longer referes to the foo created object.
I’m planning on using the controller from the foo class and the popup menu created by the bar class a lot. Therefore I’m using classes instead of creating single objects.

My question is if there is a way to deliver and process the values while still being able to do so within classes instead of objects because i want to use them multiple times.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I changed the foo and bar to Form and Popup:

1) Quick — and possibly dirty — solution:

You can send this as the second argument to .fire():

class Form {
    constructor() {
        this.property = 'yes';
    }

    eventMethod() {
        let popup = new Popup();
        popup.fire(this.endMethod, this);
    }

    endMethod(values, that) {
        console.log(values + that.property);
    }
}

class Popup {
    constructor() {
        this.property = 'no';
    }

    fire(callback, that) {
        let value = 'message';
        callback(value, that);
    }
}

let form = new Form();
form.eventMethod();

2) Using .bind()

More robustly, you can use the .bind() method to bind the Form this to endMethod before sending it out:

class Form {
    constructor() {
        this.property = 'yes';
    }

    eventMethod() {
        let popup = new Popup();
        popup.fire(this.endMethod.bind(this));
    }

    endMethod(values) {
        console.log(this);
        console.log(values + this.property);
    }
}

class Popup {
    constructor() {
        this.property = 'no';
    }

    fire(callback) {
        let value = 'message';
        callback(value);
    }
}

let form = new Form();
form.eventMethod();

Method 2

This is a simple possible solution. You can pass to the popup the whole "this" form instance

class Form {
    constructor() {
        this.property = 'yes';
    }

    eventMethod() {
        let popup = new Popup();
        popup.fire(this);
    }

    endMethod(values) {
        console.log(values + this.property);
    }
}

class Popup {
    constructor() {
        this.property = 'no';
    }

    fire(form) {
        let value = 'message';
        form.endMethod(value);
    }
}

let form = new Form();
form.eventMethod();

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply