为什么在使用 pipeline() 时,我会从 authguard 中的 Observable 得到“未定义”,而 subscribe() 可以工作,但我得到一个错误?

2024-03-20

我正在使用 PEAN 堆栈(即 PostgreSQL - ExpressJS - Angular - NodeJS)构建一个身份验证应用程序。

Problem

我的身份验证守卫有问题:

  • 如果我使用subscribe(),我在控制台中得到了预期的结果。✔ - 工作
  • 如果我使用pipe(), I get undefined在控制台中。✖ - 不工作

if-signed-in.guard.ts

import { CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth/auth.service';
import { inject } from '@angular/core';
import { tap, map } from 'rxjs/operators';
import { Router } from '@angular/router';

export const IfSignedIn: CanActivateFn = (route, state) => {
  const auth = inject(AuthService);
  const router = inject(Router);
    
  auth.getSignInStatusObserver().subscribe((res: any) => {
    console.log(res);
  });

  return auth.getSignInStatusObserver().pipe(
    tap((status) => {
      console.log(status);
    }),
    map((status) => {
      console.log(status);
      if (status) {
        if (status.success === true) {
          return true;
        } else {
          router.navigate(['/dashboard']);
          return false;
        }
      } else {
        router.navigate(['/dashboard']);
        return false;
      }
    })
  );
};

截屏:

我尝试过的

我尝试在里面实现相同的逻辑subscribe():

if-signed-in.guard.ts

import { CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth/auth.service';
import { inject } from '@angular/core';
import { Router } from '@angular/router';

export const IfSignedIn: CanActivateFn = (route, state) => {
  const auth = inject(AuthService);
  const router = inject(Router);

  auth.getSignInStatusObserver().subscribe((res: any) => {
    if (res) {
      if (res.success === true) {
        return true;
      } else {
        router.navigate(['/dashboard']);
        return false;
      }
    } else {
      router.navigate(['/dashboard']);
      return false;
    }
  });
};

但我收到以下错误:

src/app/auth/guards/if-signed-in.guard.ts:7:14 - 错误 TS2322:类型 '(路由:ActivatedRouteSnapshot,状态:RouterStateSnapshot)=> void' 不可分配给类型“CanActivateFn”。类型“void”不是 可分配给类型 'boolean |网址树 |可观察 |承诺'.

7 导出 const IfSignedIn: CanActivateFn = (路由, 状态) => {

Question

为什么我得到不明确的使用时从 authguard 中的 Observablepipe(), while subscribe()有效,但我收到错误?


EDIT 1

我已经尝试了 @MatthieuRiegler 建议的代码,但我仍然得到与上面的屏幕截图完全相同的响应。

if-signed-in.guard.ts

import { CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth/auth.service';
import { inject } from '@angular/core';
import { filter, tap, map } from 'rxjs/operators';
import { Router } from '@angular/router';

export const IfSignedIn: CanActivateFn = (route, state) => {
  const auth = inject(AuthService);
  const router = inject(Router);

  auth.getSignInStatusObserver().subscribe((res: any) => {
    console.log(res);
  });

  return auth.getSignInStatusObserver().pipe(
    filter((status) => status !== undefined),
    tap((status) => {
      console.log(status);
    }),
    map((status) => {
      console.log(status);
      if (status) {
        if (status.success === true) {
          return true;
        } else {
          router.navigate(['/dashboard']);
          return false;
        }
      } else {
        router.navigate(['/dashboard']);
        return false;
      }
    })
  );
};

EDIT 2

我的应用程序表现得很奇怪。现在我有以下代码:

if-signed-in.guard.ts

import { CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth/auth.service';
import { inject } from '@angular/core';
import { filter, tap, map } from 'rxjs/operators';
import { Router } from '@angular/router';

export const IfSignedIn: CanActivateFn = (route, state) => {
  const auth = inject(AuthService);
  const router = inject(Router);

  return auth.getSignInStatusObserver().pipe(
    filter((status) => status !== undefined),
    tap((status) => {
      console.log('Tap: ', status);
    }),
    map((status) => {
      console.log('Map: ', status);
      if (status) {
        if (status.success === true) {
          return true;
        } else {
          router.navigate(['/dashboard']);
          return false;
        }
      } else {
        router.navigate(['/dashboard']);
        return false;
      }
    })
  );
};

如果我点击编辑个人资料按钮,一切都按预期进行。 如果我在搜索栏中输入http://localhost:4200/profile/edit-profile,看起来发出值有问题,因为我收到了undefined,并且因为filter()有效,我在控制台中没有得到任何东西。

此外,页面刷新时也会发生同样的情况。似乎身份验证防护在页面刷新时不起作用。

截屏:


EDIT 3

我使用拦截器设置登录状态,如下所示:

登录状态.service.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { AuthService } from 'src/app/auth/services/auth/auth.service';

@Injectable({
  providedIn: 'root',
})
export class SignInStatusService implements HttpInterceptor {
  intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(httpRequest).pipe(
      tap((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse && httpRequest.url.endsWith('api/get-user') && event.status === 200) {
          this.authService.setSignInStatus({ success: true, response: event.body });
        }
      }),
      catchError((err: any) => {
        if (httpRequest.url.endsWith('api/get-user')) {
          this.authService.setSignInStatus({ success: false, response: err });
        }
        return throwError(() => err);
      })
    );
  }

  constructor(private authService: AuthService) {}
}

你的问题在别处。 正如你所看到的,你会得到一个undefined作为您订阅的第一个值。

通过做一个subscribe如果不关闭它,它的寿命将超过CanActivateFn.

我的猜测是您正在经历竞争状况。你的 observable 发出的状态对于CanActivateFn.

Your getSignInStatusObserver不应该发出undefined,你过滤它pipe(filter(status => status !== undefined)).这应该可以解决你的问题!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在使用 pipeline() 时,我会从 authguard 中的 Observable 得到“未定义”,而 subscribe() 可以工作,但我得到一个错误? 的相关文章

随机推荐