How can a method be called dynamically from a class in ES6?
In ES5 and lower I can do this with the following. JSFiddle example
var App = function() {
var that = this;
this.init = function() {
var elements = document.getElementsByClassName('call-method');
for(var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
that['method' + this.dataset.method](this);
});
}
};
this.methodOne = function(element) {
console.log(element.innerText);
};
this.methodTwo = function(element) {
console.log(element.innerText);
};
};
(function() {
var app = new App();
app.init();
}());
When I try to do the same in ES6 I get an error Uncaught TypeError: not a function
. Is this possible in ES6 or am I doing something wrong here? JSFiddle example
'use strict';
class App {
constructor() {
var elements = document.getElementsByClassName('call-method');
for(var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
this.constructor['method' + this.dataset.method](this); // Uncaught TypeError: not a function
App['method' + this.dataset.method](this); // Uncaught TypeError: not a function
});
}
}
methodOne(element) {
console.log(element.innerText);
}
methodTwo(element) {
console.log(element.innerText);
}
}
(function() {
new App();
}());
I think you're misunderstanding how ES6 classes work. Your first strategy is not going to work, because this.constructor is a method, not a reference to any constructor class. The second won't work, because that would only reference a static method.
Instead:
constructor() {
var elements = document.getElementsByClassName('call-method');
for(var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', (e) => {
this['method' + e.target.dataset.method](e);
});
}
}
Also arrow functions are going to be a better way to bind the event.
Edit: Updated your fiddle to show it in action - http://jsfiddle.net/dqk8n3xk/3/
You can do the following:
'use strict';
class App {
constructor() {
var that = this;
var elements = document.getElementsByClassName('call-method');
for(var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
that['method' + this.dataset.method](this);
});
}
}
methodOne(element) {
console.log(element.innerText);
}
methodTwo(element) {
console.log(element.innerText);
}
}
(function() {
new App();
}());
as shown in this jsfiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With