1

I'm using a directive to display a dialog and confirm continuation, but when returning from the directive my parent component has lost it's original scope. The console.log will return undefined.

Process: when clicking the submit button appConfirm (directive) will handle the click event and display a dialog to continue (yes/no). If yes is selected it will return back to my parent component and execute the submit function, but the scope is lost.

Any suggestions will be helpful. Thanks! A example in Plunker: https://plnkr.co/edit/CoNqz7yv8yaGMMRRarmu

Template:

<button [disabled]="disableButton" [(appConfirm)]="submit" style="primary" class="button-input btn btn-primary center-block">Submit</button>

Directive:

import {Directive, HostListener, Input} from '@angular/core';
import {SharedService} from '../../core/shared.service';
import {MdDialog} from "@angular/material";
import {Continue, Confirmation, ContinueConfirmation} from "../../dialog/dialog.component";
import {FormComponent} from '../../form/form.component'

@Directive({
  selector: '[appConfirm]',
})
export class ConfirmDirective {
    constructor(
        private sharedService: SharedService,
        private dialog: MdDialog
    ) {}

  @Input() appConfirm = () => {};
  @Input() confirmMessage = 'Are you sure you want to do this?';
  @HostListener('click', ['$event'])
  confirmFirst(event: Event) {
        let dialogRef = this.dialog.open(Confirmation,{disableClose:true});
        dialogRef.afterClosed().subscribe(result=>{
               if(result) {
                  this.appConfirm();
                }

        });
  }
}

Component:

    @Component({
      selector: 'app-form',
      templateUrl: './form.component.html',
      styleUrls: ['./form.component.css']
    })
    export class FormComponent {
        myButton: string = 'test'


        submit(){
console.log(this.myButton);
            }
    }
Tony
  • 11
  • 2

1 Answers1

4

Updated the Plunker It works now LINK

visitRangle = () => { // change is here the fat arrow function
    console.log("My button should displaY: " + this.myButton);
    console.log('Visiting rangle');
    location.href = 'https://rangle.io';
  }

The this losses it scope when used in this manner so you can use a fat arrow function to automatically bind this to the class instance:

Rahul Singh
  • 19,030
  • 11
  • 64
  • 86
  • Rahul, that works perfect. Thank you. I just did it within my local environment and worked great. Can you explain just a little bit what that syntax is doing? – Tony Aug 11 '17 at 15:35
  • @Tony when using normal functions the scope of this is lost and not bound when you return back from the directive either you have to add a `.bind(this)` syntax at the end of your method or you need to make use of fat arrow functions which preserve the value of this . like for this question a different kind of [example](https://stackoverflow.com/a/45295586/2708210) – Rahul Singh Aug 11 '17 at 15:37
  • Thanks for the quick help today. You've saved me loads of time. I seriously spent way too much time look for this answer. So...thank you! – Tony Aug 11 '17 at 15:39