Angular CanDeactivate Router Guard with an Observable Subscribed Value

社会主义新天地 提交于 2019-12-17 21:32:05

问题


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.


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!