Angular 4-Http请求错误:您在期望流的位置提供了"undefined" [英] Angular 4 - Http request error: You provided 'undefined' where a stream was expected

查看:53
本文介绍了Angular 4-Http请求错误:您在期望流的位置提供了"undefined"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试发送HTTP Post请求时,出现以下错误:

While trying to do a HTTP Post request I am receiving the following error:

auth.service.ts?c694:156出现问题,要求重新安装 密码,错误消息:您提供了流未定义的位置的未定义" 预期的.您可以提供一个Observable,Promise,Array或Iterable.

auth.service.ts?c694:156 Something went wrong requesting a new password, error message: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

在Http请求之前是另一个请求,该请求工作得很好.

The Http request is preceded by another one, which works perfectly fine.

我调用服务的组件:

requestNewPassword(formInput: NgForm) {
     if(formInput.controls['email'].value != '')
      this.authService.getApplicationAccessToken()
      .mergeMap((response: IAuthAppResponse) => this.authService.requestNewPassword(formInput, response.access_token))
      .subscribe(response => {
        // Content removed for simplicity
      })
    }

服务方法抛出错误:

public requestNewPassword(formData: NgForm, applicationAccessToken: string): Observable<any> {
      let headers = new HttpHeaders({
        'Authorization':'Bearer ' + applicationAccessToken
      });
      let email: string = formData.controls['email'].value;
      const body = {
        email: email
      };

      console.log('requestNewPassword call header: ' + headers.get('Authorization'));
      console.log('Email: ' + body.email);

      return this.http.post(this.baseUrl + '/api/user/password/forgot', body, {headers}).do(response => {
        console.log("New password was successfully sent to the e-mail adress");
      }).catch((error: HttpErrorResponse) => {
        console.log('Something went wrong requesting a new password, error message: ' + error.message);
        return Observable.throw(error);
      })
    }

每当我在表单中输入电子邮件并提交(又触发该组件的requestNewPassword方法)时,我都会从服务中收到上述错误.

Whenever I enter an email in the form and submit, which in turn triggers the requestNewPassword method of the component, I receive the error mentioned above from the service.

标头和电子邮件已正确记录,因此我认为我提供的数据没有任何内容.

The header and email are logged correctly so I don't think there's anything with the data I am providing.

由于我不知道如何调试它,所以我认为将其作为问题发布到这个令人难以置信的平台上是个好主意.

Since I have no idea how to debug this, I thought it was a good idea to post this as a question on this incredible platform.

提前谢谢!

更新

我通过不链接两个HTTP请求,而仅调用第二个HTTP请求来最小化组件中的代码,以缩小问题的范围.

I minimized the code in my component to narrow down the problem by not chaining the two HTTP requests but only call the second one, that is causing trouble.

requestNewPassword(formInput: NgForm) {
      if(formInput.controls['email'].value != '')
      this.authService.requestNewPassword(formInput, "")
       .subscribe(response => {
         // Content removed for simplicity
       })
     }

我现在获得了完整的堆栈跟踪:

I now get a full stack trace:

ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at Object.subscribeToResult (subscribeToResult.js?c011:74)
    at MergeMapSubscriber._innerSub (mergeMap.js?e2a2:132)
    at MergeMapSubscriber._tryNext (mergeMap.js?e2a2:129)
    at MergeMapSubscriber._next (mergeMap.js?e2a2:112)
    at MergeMapSubscriber.Subscriber.next (Subscriber.js?215e:89)
    at ScalarObservable._subscribe (ScalarObservable.js?d097:49)
    at ScalarObservable.Observable._trySubscribe (Observable.js?4e06:172)
    at ScalarObservable.Observable.subscribe (Observable.js?4e06:160)
    at MergeMapOperator.call (mergeMap.js?e2a2:87)
    at Observable.subscribe (Observable.js?4e06:157)
    at FilterOperator.call (filter.js?35ab:60)
    at Observable.subscribe (Observable.js?4e06:157)
    at MapOperator.call (map.js?c4af:56)
    at Observable.subscribe (Observable.js?4e06:157)
    at DoOperator.call (tap.js?7fa8:63)
    at Observable.subscribe (Observable.js?4e06:157)
    at CatchOperator.call (catchError.js?0867:79)
    at Observable.subscribe (Observable.js?4e06:157)
    at PasswordResetComponent.requestNewPassword (passwordReset.component.ts?c169:43)
    at Object.eval [as handleEvent] (PasswordResetComponent.html:7)
    at handleEvent (core.js?223c:13255)
    at callWithDebugContext (core.js?223c:14740)
    at Object.debugHandleEvent [as handleEvent] (core.js?223c:14327)
    at dispatchEvent (core.js?223c:9704)
    at eval (core.js?223c:12028)
    at SafeSubscriber.schedulerFn [as _next] (core.js?223c:4235)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js?215e:238)
    at SafeSubscriber.next (Subscriber.js?215e:185)
    at Subscriber._next (Subscriber.js?215e:125)
    at Subscriber.next (Subscriber.js?215e:89)
    at EventEmitter.Subject.next (Subject.js?c1c6:55)
    at EventEmitter.emit (core.js?223c:4203)
    at NgForm.onSubmit (forms.js?ad57:5710)
    at Object.eval [as handleEvent] (PasswordResetComponent.html:7)
    at handleEvent (core.js?223c:13255)
    at callWithDebugContext (core.js?223c:14740)
    at Object.debugHandleEvent [as handleEvent] (core.js?223c:14327)
    at dispatchEvent (core.js?223c:9704)
    at eval (core.js?223c:10318)
    at HTMLFormElement.eval (platform-browser.js?023b:2614)
    at ZoneDelegate.invokeTask (zone.js?fad3:425)
    at Object.onInvokeTask (core.js?223c:4620)
    at ZoneDelegate.invokeTask (zone.js?fad3:424)
    at Zone.runTask (zone.js?fad3:192)
    at ZoneTask.invokeTask [as invoke] (zone.js?fad3:499)
    at invokeTask (zone.js?fad3:1540)
    at HTMLFormElement.globalZoneAwareCallback (zone.js?fad3:1566)

由于这里提到了html,因此我还将提供html代码:

Since this mentions the html, I will provide the html code aswell:

<form class="custom_form" #requestNewPasswordForm="ngForm" (ngSubmit)="requestNewPassword(requestNewPasswordForm)">
    <label>E-mail</label>
    <input class="custom_input" type="email" class="inputfield form-control" ngModel name="email">
    <button class="btn btn-default" type="submit">
      Send
    </button>
</form>

推荐答案

经过大量的努力,我设法找到并解决了该问题. 问题是我有一个授权拦截器,该拦截器正在拦截每个添加带有用户访问令牌的授权标头的请求.

After a lot a lot of effort, I have managed to locate and fix the problem. The problem was that I have an authorization interceptor that is intercepting every request to add an Authorization header with a user access token.

由于我尝试进行的呼叫不需要用户访问令牌,但是需要应用程序访问令牌(身份验证为公共Http请求的应用程序,例如注册,忘记密码等),因此我决定将调用链接起来以获取应用访问令牌和对忘记密码的调用,然后将检索到的应用访问令牌传递给我服务中的忘记密码方法,并在其中的Authorization标头中进行设置.这段代码很好.问题是我已经编辑了拦截器以检查是否存在一个Authorization标头,如果不存在,那就是该错误的原因.

Since the call I was trying to do didn't require a user access token, but an application access token (authenticate as application for public Http requests like register, forgot password etc.), I decided to chain the call to get the application access token and the call for the forgotten password and just pass the retrieved application access token to the forgotten password method in my service and set it in the Authorization header there. This code was all fine. The problem was that I had edited the interceptor to check wether there was an Authorization header present and if so do nothing and THAT was the cause of the bug.

我应该只返回请求,而不做任何事情,因此它无需更改标题就可以执行.

Instead of doing nothing, I should have just returned the request, so it just gets executed without modifications to the header.

所以而不是

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if(request.headers.get('Authorization') == null) {
          //Code to add Authorization header
          return next.handle(requestWithAuthHeader)
        }
}

我必须执行以下操作:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if(request.headers.get('Authorization') == null) {
          //Code to add Authorization header
          return next.handle(requestWithAuthHeader)
        } else {
          return next.handle(request);
        }
}

否则,该请求将被拦截并且永远不会执行,因为拦截器不会将其返回. 我组件中的方法订阅了service方法的结果,因此期望可观察到的结果,但未返回任何内容,因为请求被拦截并且拦截器注意到已经存在一个Authorization标头(已在服务中设置),因此决定对请求不执行任何操作.

Otherwise the request gets intercepted and never executes because it doesn't get returned by the interceptor. The method in my component is subscribed to the result of the service method and thus expects an observable, but nothing ever gets returned because the request got intercepted and the interceptor noticed that an Authorization header was already present (set in the service) so decided to do nothing with the request.

这说明了为什么我收到错误消息,指出我的组件方法的订阅行上预期有一个流(可观察到)时提供了未定义的信息.

This explains why I got the error stating that I had provided undefined while a stream (observable) was expected on the subscribe line in my component's method.

这篇关于Angular 4-Http请求错误:您在期望流的位置提供了"undefined"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆