Igino Boffa
Igino Boffa

Reputation: 451

How to correctly define javascript prototype binding?

Can you help me to bind this function to WatcherTable object itself? Binding can be really mindblowing

WatcherTable.prototype.setRowData= function(rowData) {
  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(function () {
    this.table.api.sizeColumnsToFit();
  }, 100);
};

I already tried to do like that:

WatcherTable.prototype.setRowData= function(function(rowData) {     
  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(function () {
    this.table.api.sizeColumnsToFit();
  }, 100);
}).bind(this);

But it is obviously not working (I think this code it doesn't make any sense).

How can I properly do this?

Thank you

Upvotes: 1

Views: 61

Answers (2)

andrusieczko
andrusieczko

Reputation: 2824

The problem is not with the setRowData function but the callback in setTimeout function.

You have at least 3 different ways to fix it:

use .bind():

setTimeout(function() {
  this.something();
}.bind(this), 100);

use ES6 arrow function which preserves the current context:

setTimeout(() => {
  this.something();
}, 100);

store the current context in the variable:

var self = this;
setTimeout(function() {
  self.something();
}, 100);

Upvotes: 1

GProst
GProst

Reputation: 10237

Inside setTimeout(function(){...}) this doesn't link to WatcherTable instance anymore. Here you can read about this behavior.

You can save it beforehand in prototype.setRowData() like this

WatcherTable.prototype.setRowData = function(rowData) {

  var thisObj = this;//saving this

  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(function () {
    thisObj.table.api.sizeColumnsToFit();//using thisObj
  }, 100);

};

Or you can use ES6 arrow function inside setTimeout() like this

WatcherTable.prototype.setRowData = function(rowData) {

  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(() => {//arrow functions do not affect on 'this'
    this.table.api.sizeColumnsToFit();
  }, 100);

};

Upvotes: 1

Related Questions