Угловые «значения не определены», подписывающиеся на отображенный HTTP-ответ (запрос не выполняется?) - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть простой компонент формы входа (LoginComponent), который вызывает метод submitLogin.

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { first }  from 'rxjs/operators';

import { AuthenticationService } from '../../services';

@Component({
    selector: 'login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
    returnURL: string;

    u = new FormControl('');
    p = new FormControl('');

    constructor(private route: ActivatedRoute, private router: Router, private auth: AuthenticationService) { }

    ngOnInit() {
        this.returnURL = this.route.snapshot.queryParams['returnUrl'] || '/';
    }

    submitLogin(): void {
        this.auth.login(this.u.value, this.p.value).pipe(first()).subscribe(
            r => {
                if (r) {
                    console.log("LoginComponent: r:", r);
                    this.router.navigate([this.returnURL]);
                }
            },
            error => {
                console.error("LoginComponent: Error:", error);
            }
        );
    }

}

Ошибка, которую я получаю, печатается как LoginComponent: Error: TypeError: 'values' is undefined, и она печатаетсяв этой ошибке лямбда.

AuthenticationService выглядит (примерно) так:

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { User } from '../models/user';
import { APIService } from './api.service';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
    private currentUserSubject: BehaviorSubject<User>;
    public currentUser: Observable<User>;

    constructor(private http: HttpClient, private api: APIService) {
        this.currentUserSubject = new BehaviorSubject<User>(null);
        this.currentUser = this.currentUserSubject.asObservable();
    }
    login(u: string, p: string): Observable<boolean> {
        return this.api.login(u, p).pipe(map(
            r => {
                if (r && r.status === 200) {
                    this.updateCurrentUser();
                    console.log("returning true");
                    return true;
                }
                console.log("returning false");
                return false;
            }
        ));
    }
}

Обратите внимание, что все пути кода в лямбда-карте возвращают логическое значение.Так что эта карта никогда не должна выплевывать undefined значений.Между прочим, такие журналы консоли никогда не происходят.

И моя служба API отвечает за вызовы версионного API, который у меня работает.В нем много несвязанных вещей, но соответствующие биты:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, first } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class APIService {
    public API_VERSION = '1.5';

    private cookies: string;

    constructor(private http: HttpClient) {}

    private do(method: string, path: string, data?: Object): Observable<HttpResponse<any>> {
        const options = {headers: new HttpHeaders({'Content-Type': 'application/json',
                                                   'Cookie': this.cookies}),
                         observe: 'response' as 'response',
                         body: data};
        return this.http.request(method, path, options).pipe(map(r => {
            //TODO pass alerts to the alert service
            let resp = r as HttpResponse<any>;
            if ('Cookie' in resp.headers) {
                this.cookies = resp.headers['Cookie']
            }
            console.log("returning resp");
            return resp;
        }));
    }

    public login(u, p): Observable<HttpResponse<any>> {
        const path = '/api/'+this.API_VERSION+'/user/login';
        return this.do('post', path, {u, p});
    }
}

Обратите внимание, что снова, каждый путь кода в лямбда-карте возвращает значение.Также обратите внимание, что "returning resp" никогда не появляется в консоли.Я также никогда не вижу HTTP-запроса на сетевой панели.Что дает?Почему он не выполняет запрос и / или что может быть причиной этой ошибки?

Ответы [ 2 ]

0 голосов
/ 20 июня 2019

Если какой-либо undefined передается в заголовки на вызов HTTP, это может произойти, и это может привести к прерыванию других вызовов, если header является общим.Инициализируйте значения пустым значением по умолчанию.Это сообщение об ошибке трудно отладить.

0 голосов
/ 05 марта 2019

Отслеживание стека, которое я получил в консоли после репликации вашего кода, привело меня к функции 'lazyInit' в коде заголовков модуля Angular httpClient (node_modules\@angular\common\esm5\http\src\headers.js).

Во второй строке функции,он перебирает значения заголовка, который вы отправляете, и вы можете видеть переменную values на третьем.Там он получает один из заголовков и получает доступ к его значениям.Затем он преобразует его в массив, если это строка, а затем проверяет ее длину - в этот момент вы получаете исключение.

Если вы посмотрите на свой API-сервис, вы отправляете два заголовка:

'Content-Type': 'application/json',
'Cookie': this.cookies

И ранее вы определяете переменную cookies следующим образом:

private cookies: string;

Поскольку вы не присваиваете значение, по умолчанию используется значение * 1016.*, который затем является значением вашего заголовка Cookie, который не является строкой и также не имеет свойства length, поэтому он вызывает исключение.

Решение:

Исправлено начальное определение cookies на

private cookies = '';

.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...