Tìm kiếm trang web

angular - Lỗi: Kiểu 'boolean' không thể gán cho kiểu 'Observable'


Tôi đang làm việc trên một đoạn mã sau:

import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from '@angular/router';
import {Observable} from 'rxjs';
import {AngularFireAuth} from '@angular/fire/auth';
import {map, tap} from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class ChatGuard implements CanActivate {

  constructor(private afAuth: AngularFireAuth,
              private router: Router) {
  }


  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable <boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

      
    return this.afAuth.authState
      .pipe(
        map(user => user !== null),
        tap(value => {
          if (!value) {
            this.router.navigateByUrl('/login').then();
            return value;
          } else {
            return value;
          }
        })
      );
  }

}

Các phiên bản tôi có là:

Angular CLI: 13.1.4

Node: 16.14.0

Tôi có lỗi này trong phần mã này:

 return this.afAuth.authState
      .pipe(
        map(user => user !== null),
        tap(value => {
          if (!value) {
            this.router.navigateByUrl('/login').then();
            return value;
          } else {
            return value;
          }
        })

Nói :

Kiểu 'Observable' không thể gán cho kiểu 'boolean | UrlTree | Observable | Promise'. Kiểu 'Observable' không thể gán cho kiểu 'Observable'. Các kiểu của thuộc tính 'source' không tương thích.

Bạn có biết làm thế nào tôi có thể giải quyết việc này không?

Câu trả lời #1

Theo tài liệu, toán tử tap là "Một hàm trả về một Observable giống hệt với nguồn, nhưng thực hiện Observer hoặc callback(s) được chỉ định cho mỗi mục".

Điều này có nghĩa là bạn không phải return value trong một tap. Nó sẽ được thực hiện theo mặc định.

Mặt khác, bạn không muốn chuyển hướng tuyến đường sau khi trả về giá trị boolean, bạn cần làm điều đó trước.

Vì vậy tôi đề nghị bạn thay đổi mã của mình thành như thế này:

    return this.afAuth.authState
              .pipe(
                map(user => { 
                   const isLogged = !!user;
                   if(!isLogged){
                      this.router.navigateByUrl('/login')
                      return false;
                   } else {
                      return true
                   }
                })
);

Ngoài ra, cũng có thể xảy ra trường hợp khi làm mới trang (F5), this.afAuth.authState phát ra đầu tiên một giá trị null ngay trước đối tượng user. Điều đó sẽ khiến bạn gặp phải từ chối trong khi người dùng đã đăng nhập. Trong trường hợp đó, tôi đề nghị bạn thêm toán tử debounceTime trước map.

Câu trả lời #2

Kiểu 'Observable' không thể gán cho kiểu 'Observable'

kiểu trả về của bạn là observable trong khi trong chữ ký phương thức bạn đã định nghĩa kiểu trả về là Observable <boolean | UrlTree>

Một giải pháp khả thi là kiểm tra xem this.afAuth.authState trả về gì và cập nhật chữ ký của nó để trả về Observable<boolean | UrlTree>