0

There are times in Typescript when 'this' gets a little ambiguous. Often, what I can do is call one function from another while binding 'this', e.g.

this.myFunction.bind(this);

That way, when myFunction() calls this.whatever(), it knows what 'this' is.

In this particular case however, I'm a little lost. I am combining JQuery with Angular which, honestly, is never recommended, but sometimes you gotta work with what you're given. Anyway, the code below that is calling the function named "getSlice()" is inside of a JQuery loop which is being called from a ngAfterViewInit() event function. How do I properly call getSlice() so that the code can find it?

getSlice(val): TimeSlice {
    const data = val.split(' ');
    const slice = new TimeSlice(val[0], val[1], val[2]);
    return slice;
}

ngAfterViewInit(): void {
    let current: TimeSlice = new TimeSlice();
    $('#selectable').selectable({
        stop: function() {
            const result = $('#select-result').empty();
            $('li.ui-selected', this).each(function() {
                const val = $(this).attr('value');
                current = this.getSlice(val); <!-- Here is the problem child -->
            });
        }
    });
}
Todd Davis
  • 5,855
  • 10
  • 53
  • 89
  • Inside ngAfterViewInit => `const $_self = this`, then call `$_self.getSlice()` from jquery each. – Luciano Oct 31 '18 at 16:41
  • 2
    Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – ConnorsFan Oct 31 '18 at 16:43

2 Answers2

3

You could create the function beforehand to be safe:

ngAfterViewInit(): void {
    let getSlice = val => this.getSlice(val);

    // Or do this
    // let getSlice = this.getSlice.bind(this);

    $('#selectable').selectable({
        stop: function() {
            const result = $('#select-result').empty();
            $('li.ui-selected', this).each(function() {
                const val = $(this).attr('value');
                current = getSlice(val);
            });
        }
    });
}
Frank Modica
  • 10,238
  • 3
  • 23
  • 39
2

You can keep the reference of the this context. So you can use it later in the in nested functions later.

getSlice(val): TimeSlice {
    const data = val.split(' ');
    const slice = new TimeSlice(val[0], val[1], val[2]);
    return slice;
}

ngAfterViewInit(): void {
    let self =  this; //<-- keep `the` reference of Component
    let current: TimeSlice = new TimeSlice();
    $('#selectable').selectable({
        stop: function() {
            const result = $('#select-result').empty();
            $('li.ui-selected', this).each(function() {
                const val = $(this).attr('value');
                current = self.getSlice(val); <!-- Use self here -->
            });
        }
    });
}
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48