0

I've been using let _this = this or _component for a while to reference the scope of angular components when functions become complex and include a couple of levels of nesting.

This was recommended to me in a question months ago to get around the issue of accessing the correct scope within such functions, but is there any way that I can get around this and consistently reference the scope of the component itself just using this as the identifier?

I've had a look for anything that ES6 might be able to fix this with, but can't figure out a way to solve this issue.

Example - _this overload:

addPayment() {
    let _this = this;

    console.log('ViewInvoice.addPayment()');

    this.newPaymentDialogRef = this.dialog.open(NewPaymentDialogComponent, {
        hasBackdrop: true,
        data: {
            userId: _this.authService.user.uid,
            invoice: _this.invoice,
            payments: _this.payments
        }
    })

    this.newPaymentDialogRef.afterClosed().subscribe(payment => {
        if (payment) {
            _this.payments.push(payment);
            _this.paymentsData.data = _this.payments;

            _this.db.collection('/users').doc(_this.authService.user.uid).collection('/invoices').doc(_this.invoice.id).collection('/payments').doc(payment.id).set(payment)
                .then(function(docRef) {
                    console.log('ViewInvoice.addPayment() - New payment saved:', payment);
                    _this.notifService.showNotification('Payment added', 'Close');
                })
                .catch(function(error) {
                    console.error(`ViewInvoice.addPayment() - Error saving new payment: ${error.message}`);
                    _this.notifService.showNotification(`Error adding new payment: ${error.message}`, 'Close');
                })

            _this.calcPaymentTotals(payment);
        }
    })
}
nick.cook
  • 2,071
  • 4
  • 18
  • 36
  • 1
    Just use arrow functions instead (as you're using properly in some places)? – CertainPerformance Jun 19 '18 at 10:34
  • I don't understand how I would use the arrow function for much of it though, like the line where I've got if(payment)... – nick.cook Jun 19 '18 at 10:37
  • Just replace every `function` with an arrow function, and replace every `_this` with `this`, and you're good to go, I think – CertainPerformance Jun 19 '18 at 10:40
  • In the example above for the newPaymentDialogRef.afterClosed().subscribe() method, how would this be done for an if statement to prevent the use of _this as shown? That's what I don't understand – nick.cook Jun 19 '18 at 10:42
  • You're only calling functions there, not creating functions, it's nothing to worry about, and your `payment => {` is already an arrow function. – CertainPerformance Jun 19 '18 at 10:51
  • Yes, but because of having content within the if statement, I cannot refer to 'this', it has to be '_this'. Only using 'this' within the if statement breaks the function, likewise with the function above. – nick.cook Jun 19 '18 at 10:52
  • Huh? `if` statements do not create new calling contexts. (You can also reduce the indentation problems there with `if (!payment) return;` at the top) – CertainPerformance Jun 19 '18 at 10:56
  • eg https://jsfiddle.net/ga8x60q5/ works just fine – CertainPerformance Jun 19 '18 at 10:58
  • Good suggestion at the end, thanks. I know an if statement shouldn't create new context, but it's causing this issue. Theoretically, this function shouldn't require _this, but it does – nick.cook Jun 19 '18 at 10:59
  • 1
    The code in your question still has full-fledged `function`s below, if you haven't noticed: `.then(function(docRef) {` etc Those are the ones you need to replace with arrow functions. The `if` statement cannot be causing the calling context problem – CertainPerformance Jun 19 '18 at 11:00
  • Thanks, I've just considered that. I've managed to refactor the then and catch functions to completely remove any instance of _this in addPayment() – nick.cook Jun 19 '18 at 11:11

0 Answers0