I created unsaved.guard.ts to make it as guard to ask user if they want give up saving data when the user quit the editing page.
when i run the project, it keeps telling me , return type error. But it looks fine. Please anyone can give me some clues, also below the whole project in the git: https://github.com/codezj/angular-route-guard
import { Component, Injectable } from "@angular/core";
import {CanActivate,
ActivatedRouteSnapshot,RouterStateSnapshot,Router, UrlTree, TitleStrategy
} from "@angular/router"
import { MessageService } from "../messages/message.service";
import { Message } from "../messages/message.model";
import { Observable, Subject } from "rxjs";
import { FormComponent } from "./form.component";
@Injectable()
export class UnsavedGuard implements CanActivate{
constructor(private messages: MessageService, private router: Router){
}
canActivate(component: FormComponent, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
if (component.editing){
if (["name","category","price"]
.some(prop=> component.product["name"]
!= component.originalProduct["name"]))
{
let subject = new Subject<boolean>();
let responses : [string, (string: any )=> void][] =[
["Yes", () => {
subject.next(true);
subject.complete();
}],
["No", ()=>{
this.router.navigateByUrl(this.router.url);
subject.next(false);
subject.complete();
}
]
];
this.messages.reportMessage(
new Message("Discard Changes?",
true, responses));
return subject;
}
// else {
// return true;
// }
}
return true;
}
}
Build at: 2022-12-11T05:51:15.893Z - Hash: 9449b56719e1a6f8 - Time: 721ms
Error: src/app/core/unsaved.guard.ts:18:5 - error TS2416: Property 'canActivate' in type 'UnsavedGuard' is not assignable to the same property in base type 'CanActivate'.
Type '(component: FormComponent, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | UrlTree | Observable<...> | Promise<...>' is not assignable to type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | UrlTree | Observable<boolean | UrlTree> | Promise<...>'.
18 canActivate(component: FormComponent, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
~~~~~~~~~~~
× Failed to compile.
I tried to change different return types for the guard functions. Not solved the issue.
Actually, when i use below way in another guard, it works fine.
import { Injectable } from "@angular/core";
import {CanActivate,
ActivatedRouteSnapshot,RouterStateSnapshot,Router, UrlTree, TitleStrategy
} from "@angular/router"
import { MessageService } from "./messages/message.service";
import { Message } from "./messages/message.model";
import { TmplAstRecursiveVisitor } from "@angular/compiler";
import { Observable } from "rxjs";
@Injectable()
export class TermsGuard implements CanActivate {
constructor(private messages: MessageService,
private router: Router){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
// throw new Error("Method not implemented.");
if (route.params["mode"] == "create") {
return new Promise<boolean>((resolve)=>{
let responses: [string, ()=> void][]
=[["Yes",()=> resolve(true)], ["No", ()=> resolve(false)]];
this.messages.reportMessage(new Message("Do you accept the terms @ conditions?", false,responses))
});
}
else {
return true;
}
}
// canActivte(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
// Promise<boolean> | boolean {
// }
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Promise<boolean> | boolean {
if (route.url.length>0
&& route.url[route.url.length-1].path == "categories"){
return new Promise<boolean>((resolve, reject) =>{
let responses: [string, (string:any)=>void][] = [
["Yes", ()=> resolve(true)],
["No ",()=>resolve(false)]
];
this.messages.reportMessage(
new Message("Do you want to see the categories component?", false, responses)
)
})
}
else {
return true;
}
}
}
You can't have a component as a parameter of the canActivate
function. It has to be implemented with only two parameters: route: ActivatedRouteSnapshot
and state: RouterStateSnapshot
. The error message tells exactly that.