Here is my canDeactivate guard and it works. But I dont want to call the guard when I use the submit button. Only when I navigate by any other means. How?
import { Injectable } from '@angular/core';
import { Router, CanDeactivate } from '@angular/router';
import { FormGroup } from '@angular/forms';
export interface FormComponent {
myForm: FormGroup;
}
@Injectable()
export class DirtyGuard implements CanDeactivate<FormComponent> {
constructor(private router: Router) {}
canDeactivate(component: FormComponent) {
console.log(component.myForm)
if (component.myForm.dirty ){
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
}
return true;
}
}
<button md-raised-button [disabled]="!myForm.valid" type="submit" color="primary">
<i class="material-icons">arrow_forward</i>
Exposures: Currencies
</button>
The Angular CanDeactivate guard is called, whenever we navigate away from the route before the current component gets deactivated. The best use case for CanDectivate guard is the data entry component. The user may have filled the data entry and tries to leave that component without saving his work.
CanDeactivate is a TypeScript interface that needs to be implemented by a component to create a route guard. This guard will be used by the router to decide if the route can be deactivated. It can be implemented in any Angular component using the canDeactivate method of the interface.
CanActivate - Decides if a route can be activated. CanActivateChild - Decides if children routes of a route can be activated. CanDeactivate - Decides if a route can be deactivated. CanLoad - Decides if a module can be loaded lazily.
[angular v.4 - untested on v.2, but should work]
The guard 'canDeactivate' is correctly getting called, but you just want to return true for the scenario where you've submitted, so how can we determine that? You already have a handle to the FormGroup, however this does not appear to have a property relating to submitted. As an alternative, you can obtain a handle to your form using the @ViewChild decorator within your component class, like so:
@ViewChild('myForm') myForm;
In order for this to work you'll have to add a local variable for your form, like so:
<form #myForm="ngForm" (ngSubmit)="onSubmit()">
you will then see a property on the myForm object called _submitted. This allows you to update your if condition to only show the confirm message if dirty && !submitted. e.g.:
if (this.myForm.form.dirty && !this.myForm._submitted ){
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
}
return true;
I'm assuming you've already worked round this issue, based on the date posted, but this might serve to explain what was going on at least.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With