繁体   English   中英

Angular'值未定义'订阅映射的http响应(请求没有被生成?)

[英]Angular 'values is undefined' subscribing to mapped http response (request not being made?)

我有一个简单的登录表单组件( 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 ,并且它被打印在该错误lambda中。

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;
            }
        ));
    }
}

请注意,map lambda中的所有代码路径都返回一个布尔值。 所以这个地图永远不应该吐出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});
    }
}

请注意,map lambda中的每个代码路径都会返回一个值。 另请注意, "returning resp"永远不会出现在控制台中。 我也从未在网络面板中看到HTTP请求。 是什么赋予了? 为什么不执行请求,和/或可能导致此错误的原因?

复制代码后我在控制台中得到的堆栈跟踪使我进入了Angular的httpClient模块( node_modules\\@angular\\common\\esm5\\http\\src\\headers.js )的头文件代码中的'lazyInit'函数。

在函数的第二行,它迭代你提交的标题的值,你可以在第三行看到values变量。 在那里它获得一个标题并访问它的值。 接下来,它将它转换为数组,如果它是一个字符串,然后检查它的长度 - 此时你得到异常。

如果你查看你的API服务,你提交的标题有两个:

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

之前,您可以像这样定义cookies变量:

private cookies: string;

由于您没有分配值,因此默认为undefined ,即“Cookie”标头的值,该标头不是字符串,也没有length属性,因此它会抛出异常。

解:

cookies的初始定义更改为

private cookies = '';

解决这个问题。

如果将任何undefined值传递给HTTP调用的头文件,则会发生这种情况,并且如果header是常见的,则可能导致其他调用被破坏。 使用默认空值初始化值。 此错误消息很难调试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM