I've been trying to write a canDeactivate guard to check a saving state from an observable stream and work accordingly.
My service goes as this
import { Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class EditModelService {
private savingModelDataSource = new ReplaySubject<boolean>();
savingModelData$ = this.savingModelDataSource.asObservable();
public setSavingModelData(state: boolean) {
this.savingModelDataSource.next(state);
}
}
My guard goes as
import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { EditModelService } from './edit-model.service';
@Injectable()
export class EditModelCanDeactivateGuardGuard {
private savingState: boolean;
constructor(
private editModelService: EditModelService
) { }
CanDeactivate(
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
this.editModelService.savingModelData$.subscribe(saving => {
this.savingState = saving;
});
if (this.savingState) {
return this.editModelService.savingModelData$.first();
} else {
return this.editModelService.savingModelData$.first();
}
}
}
Basically, it takes the value of the savingState from the service and returns according to the state so the router's canDeactivate attribute receives a boolean. Since the value this.savingState in the guard is always subscribed I don't think there is an issue with the conditional goes below.
With some search I came across this answer and tried doing the guard code as
return this.editModelService.savingModelData$.first();
Of course, I've imported first() here as import 'rxjs/add/operator/first';
.
It returns an observable from the guard just to see whether that is working fine or if that is something to do with the way I am returning. But, in both of the scenarios, I get the error as shown in the image below.
I've provided the router guard inside the module where the router configuration is imported. That's where the service is provided as well.
What am I doing here wrong? I am new to using router guards(especially, canDeactivate with an observable) and any help is appreciated.
Your Guard Service must implement function to fully implement that CanActivate
or CanDeactivate
interface. Try changing as
From
@Injectable()
export class EditModelCanDeactivateGuardGuard {
To
@Injectable()
export class EditModelCanDeactivateGuardGuard implements CanActivate, CanDeactivate<boolean>{
also your CanDeactivate
should be changed to canDeactivate
canDeactivate() {
}
Updated after trying out the solution:
Also, change
From
canDeactivate(
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean ...
To
canDeactivate(): Observable<boolean> | Promise<boolean> | boolean...
来源:https://stackoverflow.com/questions/49027861/angular-candeactivate-router-guard-with-an-observable-subscribed-value