ERROR Ошибка: Uncaught (в обещании): TypeError: не удается прочитать свойство «длина» неопределенного значения в Angular 7 и rxjx

Недавно я обновил свое приложение 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.

Любая помощь будет оценена по достоинству!


person Fabian    schedule 15.11.2018    source источник
comment
Похоже, проблема именно в этой строке map(res => !!res.length). Чего именно вы ждете от response   -  person SiddAjmera    schedule 15.11.2018
comment
Вы одновременно переходили с Http на HttpClient? HttpClient возвращает другой ответ. Я имею в виду, что по умолчанию для тела он указывает не весь объект ответа.   -  person magos    schedule 15.11.2018
comment
Вы можете изменить это поведение, передав объект { observe: 'response' } в качестве параметров (второй параметр) методу http.get().   -  person magos    schedule 15.11.2018
comment
@Magos, я могу решить проблему с Http, но не с HttpClient. См. Обновленный вопрос по коду.   -  person Fabian    schedule 15.11.2018


Ответы (1)


HttpClient по умолчанию указывает тело ответа, а не весь объект ответа. Если вы одновременно переходите с Http на HttpClient - для совместимости с предыдущим способом - используйте объект параметров, чтобы вернуть весь ответ в обратном вызове.

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