Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do not use CanDeactivate guard when using submit button

Tags:

angular

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>
like image 603
Tampa Avatar asked Mar 18 '17 04:03

Tampa


People also ask

What are the responsibilities of the CanDeactivate guard in angular?

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.

Can you deactivate component?

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.

What is the difference between CanActivate and CanDeactivate?

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.


1 Answers

[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.

like image 188
David Douglas Anderson Avatar answered Sep 23 '22 05:09

David Douglas Anderson