Problem with child reach of this in Typescript

This is MANDATORY just like any other this question I have read so far, except for one slight difference, which makes it relevant (imo) to ask this question.

Now, initially my problem was to define the scope of this using Knockout and Typescript, so the following is given:

 class ViewModel { public SomeObservableArray = new ko.observableArray(); public AddToTheObservableArray(someJsonData: any) { this.SomeObservableArray.push(new SomePojo(someJsonData)); } } 

So, the this bit in the code above will explode because Typescript makes you think that this is an instance of the class, but actually it is something else due to the ajax callback or view element, regardless of the script that overrides the key the word this .

So, to fix this, most solutions should move this code into the constructor for a class that I personally find terrible, however this small amount of horror is acceptable, given the other benefits that I get from using TypeScript. Therefore, we are all on one page, the code below fixes the problem:

 class ViewModel { public SomeObservableArray = new ko.observableArray(); public AddToTheObservableArray = (someJsonData: any) => Void; constructor { this.AddToTheObservableArray = (someJsonData: any) => { this.SomeObservableArray.push(new SomePojo(someJsonData)); }; } } 

I just write this example code from the head, so I apologize for any typos, etc., but it raises the general problem and spreads the solution / work.

NOW! The problem is, I have the next step from here, I have this code:

 class ViewModel { public SomeObservableArray = new ko.observableArray(); public AddToTheObservableArray = (someJsonData: any) => Void; constructor { this.PopulateObservableArray = (someJsonArrayData: any) => { this.SomeObservableArray.removeAll(); someJsonArrayData.forEach(function(someJsonData) { this.SomeObservableArray.push(new SomePojo(someJsonData)); }); }; } } 

The resulting code looks like this:

 var ViewModel = (function(){ function ViewModel(){ var _this = this; this.SomeObservableArray = new ko.observableArray(); this.AddMultipleEntitiesToObservableArray = function(someJsonArrayData) { _this.SomeObservableArray.removeAll(); someJsonArrayData.forEach(function(someJsonData) { this.SomeObservableArray.push(new SomePojo(someJsonData)); }); } }; return ViewModel; })(); 

Again, I apologize for any typos, as I am simply simplifying the output of large projects, but the main thing to see here is that the forEach child this methods remain, so I get this.SomeObservableArray is undefined error.

I am sure that one possible solution is to extract the foreach and create its own method, but then it seems to stick the cellotepa to the blutack, so I was wondering if there is an even more elegant solution or some misconduct on my part that can be changed, by at least in order to make it more unreadable.

+3
source share
1 answer

Yes, there is, and it is actually quite easy. Just use the lambda expression in any method that you want to span the scope of a higher function. In your case, you need to rewrite your example as:

 class ViewModel { public SomeObservableArray = new ko.observableArray(); public AddToTheObservableArray = (someJsonData: any) => Void; constructor() { this.PopulateObservableArray = (someJsonArrayData: any) => { this.SomeObservableArray.removeAll(); someJsonArrayData.forEach((someJsonData) => { this.SomeObservableArray.push(new SomePojo(someJsonData)); }); }; } } 

PS: it is considered best practice not to manipulate the observed array in for everyone, since the subscribers of this array will be notified with every change. Just push your data into a temporary array and then set that array as the value of your observable array (only my 2cts.)

+6
source

All Articles