簡體   English   中英

Angular 4 - Http請求錯誤:您在預期的流中提供了“undefined”

[英]Angular 4 - Http request error: You provided 'undefined' where a stream was expected

在嘗試執行HTTP Post請求時,我收到以下錯誤:

auth.service.ts?c694:156請求新密碼時出錯了,錯誤消息:您提供了“未定義”的預期流。 您可以提供Observable,Promise,Array或Iterable。

Http請求之前是另一個請求,它完全正常。

我的組件調用服務:

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方法時,我就會從服務中收到上述錯誤。

標題和電子郵件已正確記錄,因此我認為我提供的數據沒有任何內容。

由於我不知道如何調試這個,我認為在這個令人難以置信的平台上發布這個問題是一個好主意。

提前致謝!

更新

我最小化了組件中的代碼,通過不鏈接兩個HTTP請求來縮小問題范圍,但只調用第二個HTTP請求,這會導致麻煩。

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

我現在得到一個完整的堆棧跟蹤:

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代碼以及:

<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>

經過了很多努力,我設法找到並解決了問題。 問題是我有一個授權攔截器,它攔截每個請求添加一個帶有用戶訪問令牌的Authorization頭。

由於我試圖做的調用不需要用戶訪問令牌,而是一個應用程序訪問令牌(作為公共Http請求的應用程序進行身份驗證,如注冊,忘記密碼等),我決定鏈接調用以獲取應用程序訪問權限令牌和忘記密碼的調用,只需將檢索到的應用程序訪問令牌傳遞給我服務中的忘記密碼方法,並將其設置在Authorization標頭中。 這段代碼都很好。 問題是我編輯了攔截器以檢查是否存在授權標頭,如果沒有這樣做,那就是錯誤的原因。

我應該剛剛返回請求,而不是什么都不做,所以它只是在沒有修改標題的情況下執行。

而不是

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

否則,請求被攔截並且永遠不會執行,因為它不會被攔截器返回。 我的組件中的方法訂閱了服務方法的結果,因此期望一個observable,但是沒有任何東西被返回,因為請求被攔截並且攔截器注意到Authorization頭已經存在(在服務中設置)所以決定對請求不做任何事。

這解釋了為什么我得到錯誤聲明我提供了undefined,而在我的組件方法的訂閱行上預期了一個流(observable)。

我有一個非常相似的問題。 它最終也成為HTTP攔截器的問題。 我有一個自動反序列化函數在具有特定API端點模式的所有響應上運行。 不是HTTPResponse實例的響應最終被吃掉了。 在不是HTTPResponse實例的情況下添加一個返回響應未觸及的else語句為我解決了這個問題:

@Injectable()
export class DeserializerInterceptor implements HttpInterceptor {
  public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).map(
      event => {
        if (event instanceof HttpResponse) {
          let response = event as HttpResponse<any>;
          // ... deserialization of response object
          return response;
        } else {
          return event; // ... adding this else statement fixed the `undefined` error.
        }
      }
    );
  }
}

(為清楚起見,刪除了錯誤處理代碼。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM