Kiran Mohan
Kiran Mohan

Reputation: 3006

javascript: how to access the right context

I need to write a Javascript code like shown below. Problem is I cannot access "this" (it should point to "obj" on line 1) from within _notifHandlers.typeA, _notifHandlers.typeB or _notifHandlers.typeGeneric.

I understand that I can pass "this" as paramerter to these functions and use it to access the right context. But is there a better way?

var obj = {
    handleNotification : function(managedObj) {

        if (this._notifHandlers.hasOwnProperty(managedObj.id)) {
            this._notifHandlers[managedObj.id](managedObj);
        } else {
            this._notifHandlers.typeGeneric(managedObj);
        }

    },

    _notifHandlers : {
        typeA : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelA"; // TODO:
            this.showUI(managedObj, model);
        },
        typeB : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelB"; // TODO:
            this.showUI(managedObj, model);
        },
        typeGeneric : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "typeGeneric"; // TODO:
            this.showUI(managedObj, model);
        }
    },

    showUI : function(managedObj, model) {
        // TODO:
        console.log("In showUI(): model -> " + model)
    }
}

var managedObject = {
    id : "typeB"
}

obj.handleNotification(managedObject);

Upvotes: 0

Views: 89

Answers (2)

Chirag Ravindra
Chirag Ravindra

Reputation: 4830

You can always use bind to create instances of a function with the context correctly initialized

function show(){
    console.log(this.x);
}

x = 10;
var obj = {
    x: 5,
    y:{}
}

// Use bind to create an instance of the function show with the context set to obj and set it to an inner proerty of obj (to mimic the structure of the original posted code)
obj.y.show = show.bind(obj);

show(); //Logs 10 from the global window context
obj.y.show() // Logs 5 with this bound to obj

You can also use call and apply to set the context at the time of invocation.

show.call(obj);  // Logs 5
show.apply(obj);  // Logs 5

Upvotes: 1

Andrei Todorut
Andrei Todorut

Reputation: 4526

Use the call method

Working fiddle https://jsfiddle.net/andreitodorut/an15zkja/

var obj = {
    handleNotification : function(managedObj) {

        if (this._notifHandlers.hasOwnProperty(managedObj.id)) {
            this._notifHandlers[managedObj.id].call(this,managedObj);
        } else {
            this._notifHandlers.typeGeneric.call(this,managedObj);
        }

    },

    _notifHandlers : {
        typeA : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelA"; // TODO:
            this.showUI(managedObj, model);
        },
        typeB : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelB"; // TODO:
            this.showUI(managedObj, model);
        },
        typeGeneric : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "typeGeneric"; // TODO:
            this.showUI(managedObj, model);
        }
    },

    showUI : function(managedObj, model) {
        // TODO:
        console.log("In showUI(): model -> " + model)
    }
}

var managedObject = {
    id : "typeB"
}

obj.handleNotification.call(obj,managedObject);

Upvotes: 1

Related Questions