【问题标题】:ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'length' of undefined in Angular 7 and rxjx错误错误:未捕获(承诺):TypeError:无法读取Angular 7和rxjx中未定义的属性“长度”
【发布时间】:2019-04-18 16:11:55
【问题描述】:

我最近将我的 Angular 2 应用程序升级到了 Angular 7。我遇到的挑战之一是 user.service.ts 我有 isAuthentiated 方法。基本上,这个方法被传递到auth.guard.ts,这样如果他们的用户名不在我的列表中,我就可以指导用户。

用户服务检索用户,然后 isAuthenticated 检查用户。 Auth Guard 正在检查用户。如果用户在列表中,则授予访问权限,否则将其导航到某个网站。

user.service.ts

import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { map, catchError, tap } from 'rxjs/operators';
import { HttpClient  } from '@angular/common/http';
import { Observable, of } from 'rxjs';

@Injectable()
export class UserService {
    baseUrl = environment.apiUrl;

    constructor(private http: HttpClient) { }

    private extractData(res: Response) {
        const body = res;
        return body || { };
    }

    ... other methods

    isAuthenticated(): Observable<boolean> {
        return this.http.get(this.baseUrl + 'users').pipe(
            map(this.extractData),
            map(res => !!res.length)
        );
    }
}

而我的auth.guard.ts 是:

import { UserService } from './../_services/user.service';
import { Injectable } from '@angular/core';
import { CanActivate, RouterStateSnapshot, Router } from '@angular/router';
import { AlertifyService } from '../_services/alertify.service';
import { map } from 'rxjs/operators';


@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
    private userService: UserService,
    private alertifyService: AlertifyService,
    private router: Router
  ) {}

  canActivate(route, state: RouterStateSnapshot) {
    return this.userService.isAuthenticated().pipe(map(user => {
      if (!user) {
        return true;
      } else {
        this.router.navigate(['/authentication/get-jhed']);
        this.alertifyService.error('You need to be authenticated to access this area');
        return false;
      }
    }));
  }
}

此代码返回以下错误:

错误错误:未捕获(承诺中):TypeError:无法读取未定义的属性“长度”

我试过res[0].length我没有收到错误但这次什么也没发生。

我可以使用Http 解决这个问题,如下所示:

isAuthenticated(): Observable<boolean> {
    return this.http.get(this.baseUrl + 'users').pipe(
        map(res => res.json()),
        map(res => !!res.length)
    );
}

请注意,我在这里使用Http,而不是HttpClient

任何帮助将不胜感激!

【问题讨论】:

  • 看来问题出在map(res =&gt; !!res.length)这一行。您对response 的期望究竟是什么?
  • 你是不是同时从Http迁移到HttpClient? HttpClient 返回其他响应。我的意思是它默认表示一个主体而不是整个响应对象。
  • 您可以通过将{ observe: 'response' } 对象作为选项(第二个参数)传递给http.get() 方法来更改该行为。
  • @Magos,我可以用Http 解决问题,但不能用HttpClient。请查看代码的更新问题。

标签: javascript angular typescript rxjs angular7


【解决方案1】:

HttpClient 默认情况下表示响应体而不是整个响应对象。如果您同时从 Http 迁移到 HttpClient - 为了与以前的方式兼容 - 使用选项对象在回调中返回整个响应。

isAuthenticated(): Observable<boolean> {
    return this.http.get(this.baseUrl + 'users', { observe: 'response' }).pipe(
        map(this.extractData),
        map(res => !!res.length)
    );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2021-04-18
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多