Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 : Use CanDeactivate, but showing modals instead of a window.confirm

How can I use CanDeactivate using a bootstrap modal instead of a confirm? The fact is: how do I return an observable doing this process?

The code is the following. CheckoutComponent is the same component and I have the modal and the one I want to prevent from deactivating

public modalResponse: Observable<boolean> = new Observable((observer) => { });

public saveChanges() { ///OPEN MODAL AFTER CANDEAC
    this.openSaveChangeModal();
    return this.modalResponse.take(1);
}

canDeactivate(component: CheckoutComponent){
    if(this.nav)
        return true;

    else{
        component.saveChanges(); // Opens modal
    return component.modalResponse.take(1);
    }
}

// Modal save changes
public openSaveChangeModal() {
    jQuery('#deactModal').modal();
}

public acceptNavigate(){
    this.modalResponse = new Observable((observer) => {observer.next(true); });
    jQuery('#deactModal').modal('hide');
}

public cancelNavigate(){
    this.modalResponse = new Observable((observer) => { observer.next(false); });

    jQuery('#deactModal').modal('hide');
}

But I am dealing with

TypeError: Cannot read property 'saveChanges' of undefined

like image 597
Dani Villanueva Avatar asked Dec 19 '16 08:12

Dani Villanueva


1 Answers

It would be probably better to return a Promise instead of an Observable, as you need a boolean answer just once. You can then add click events to the buttons of the modal resolving the promise:

canDeactivate(): Promise<boolean> {

        let $modal = jQuery('#deactModal').modal();
        return new Promise<boolean>((resolve, reject) => {
          document.getElementById("btnAccept").onclick = ((e: any) => {
              jQuery('#deactModal').modal('hide');
              resolve(true);
          });

          document.getElementById("btnCancel").onclick = ((e: any) => {
              jQuery('#deactModal').modal('hide');
              resolve(false);
          });

          $modal.modal("show");

        });  
}

You could avoid using event handlers with the angular bootstrap library instead of the jQuery bootstrap.

like image 64
MazarD Avatar answered Nov 09 '22 10:11

MazarD