In my Angular 4 application I have some components with a form, like this:
export class MyComponent implements OnInit, FormComponent {
form: FormGroup;
ngOnInit() {
this.form = new FormGroup({...});
}
they use a Guard service to prevent unsubmitted changes to get lost, so if the user tries to change route before it will ask for a confirmation:
import { CanDeactivate } from '@angular/router';
import { FormGroup } from '@angular/forms';
export interface FormComponent {
form: FormGroup;
}
export class UnsavedChangesGuardService implements CanDeactivate<FormComponent> {
canDeactivate(component: FormComponent) {
if (component.form.dirty) {
return confirm(
'The form has not been submitted yet, do you really want to leave page?'
);
}
return true;
}
}
This is using a simple confirm(...)
dialog and it works just fine.
However I would like to replace this simple dialog with a more fancy modal dialog, for example using the ngx-bootstrap Modal.
How can I achieve the same result using a modal instead?
In addition to ShinDarth's good solution, it seems worth mentioning that you will have to cover a dismissal of the modal as well, because the action() method might not be fired (e.g. if you allow the esc button or click outside of the modal). In that case the observable never completes and your app might get stuck if you use it for routing.
I achieved that by subscribing to the bsModalService
onHide
property and merging this and the action subject together:In my case I map the mentioned
onHide
observable to false because a dismissal is considered an abort in my case (only a 'yes' click will yield a positive outcome for my confirmation modal).I solved it using ngx-bootstrap Modals and RxJs Subjects.
First of all I created a Modal Component:
here's the template:
Then I modified my guard using a Subject, now it look like this:
This is my implementation to get a confirmation dialog before leaving a certain route using ngx-bootstrap dialog box. I am having a global variable called 'canNavigate' with the help of a service. This variable will hold a Boolean value if it is true or false to see if navigation is possible. This value is initially true but if I do a change in my component I will make it false therefore 'canNavigate' will be false. If it is false I will open the dialog box and if the user discards the changes it will go to the desired route by taking the queryParams as well, else it will not route.