Issue with canDeactivate : "Type 'CanDeactivate' is not generic"
Asked Answered
M

1

8

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;
    }
}
Myra answered 17/2, 2019 at 7:12 Comment(2)
Welcome to SO. Why are you importing CanDeactivate from @angular/router/sr/utils?Topi
Not an Angular expert. Would help if you stated what version you are using. However, your question took an interest in me as I like learning new frameworks. I did find a blog with similar code than yours but has its differences. Take a look here: scotch.io/courses/routing-angular-2-applications/candeactivateLuganda
S
5

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>
Suh answered 17/2, 2019 at 11:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.