Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with canDeactivate : "Type 'CanDeactivate' is not generic"

I am trying to set up a simple canDeactivate guard in Angular 7, and I have tried code from a number of online tutorials, but they all yield the same error:

"Type 'CanDeactivate' is not generic."

What am I doing wrong? I can't even find this error on any google hits other than another 2 year old unanswered question with same issue.

See code here:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { CanDeactivate } from '@angular/router/src/utils/preactivation';

export interface CanDeactivateComponent {
    canDeactivate: () => Observable<boolean> | boolean;
}

@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanDeactivateComponent> {
    canDeactivate(component) {
        return component.canDeactivate ? component.canDeactivate() : true;
    }
}
like image 834
Bententious Avatar asked Feb 17 '19 07:02

Bententious


People also ask

What is the difference between Canactivate and CanDeactivate?

CanActivateChild - Decides if children routes of a route can be activated. CanDeactivate - Decides if a route can be deactivated.

What is CanDeactivate?

CanDeactivatelinkInterface that a class can implement to be a guard deciding if a route can be deactivated. If all guards return true , navigation continues. If any guard returns false , navigation is cancelled.


1 Answers

Your CanDeactivate import is wrong. You have to import it from @angular/router like this:

import { CanDeactivate } from '@angular/router';

This will export the right interface to use in your project. It is a generic interface with a type parameter for your component type:

export interface CanDeactivate<T> {
  canDeactivate(
      component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot,
      nextState?: RouterStateSnapshot): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean
      |UrlTree;
}

According to your import, the file preactivation.ts in the Angular repository exports an interface with the same name but whose usage seems to be internal to the angular library and not meant to be used outside of it:

export class CanDeactivate {
  constructor(public component: Object|null, public route: ActivatedRouteSnapshot) {}
}

This interface is not generic and has no type parameter, which is why you get an error when using it like this:

CanDeactivate<CanDeactivateComponent>
like image 145
jo_va Avatar answered Oct 07 '22 02:10

jo_va