Angular 4 - Http-förfrågningsfel: Du angav 'undefined' där en ström förväntades


När jag försöker göra en HTTP POST-förfrågan får jag följande fel:

auth.service.ts?c694:156 Något gick fel när en ny lösenord begärdes, felmeddelande: Du angav 'undefined' där en ström förväntades. Du kan ange en Observable, Promise, Array eller Iterable.

Http-begäran föregås av en annan, som fungerar helt felfritt.

Min komponent som anropar tjänsten:

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

Tjänstmetoden som kastar felet:

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

När jag anger en e-postadress i formuläret och skickar, vilket i sin tur triggar komponentens requestNewPassword-metod, får jag det ovan nämnda felet från tjänsten.

Rubriken och e-posten loggas korrekt, så jag tror inte att det är något fel med de uppgifter jag tillhandahåller.

Eftersom jag inte har någon aning om hur man felsöker detta, tyckte jag att det var en bra idé att posta detta som en fråga på denna otroliga plattform.

Tack i förväg!

Uppdatering

Jag minimerade koden i min komponent för att begränsa problemet genom att inte kedja de två HTTP-förfrågningarna utan bara kalla på den andra, som orsakar problem.

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

Jag får nu en fullständig stacktrace:

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)

Eftersom detta nämner HTML, kommer jag också att tillhandahålla HTML-koden:

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

Svar #1

Efter mycket, mycket ansträngning har jag lyckats lokalisera och åtgärda problemet. Problemet var att jag har en autentiseringsinterceptor som avlyssnar varje begäran för att lägga till en auktoriseringsheader med en användartillgångstoken.

Eftersom anropet jag försökte göra inte krävde en användartillgångstoken, utan en applikationstillgångstoken (autentisera som applikation för offentliga HTTP-förfrågningar som registrera, glömt lösenord etc.), bestämde jag mig för att kedja anropet för att få applikationstillgångstoken och anropet för det glömda lösenordet och bara skicka den hämtade applikationstillgångstoken till metoden för glömt lösenord i min tjänst och ställa in den i Authorization-headern där. Denna kod fungerade helt fint. Problemet var att jag hade redigerat interceptorn för att kontrollera om det fanns en Authorization-header närvarande och om så var fallet göra ingenting och DET var orsaken till buggen.

Istället för att göra ingenting borde jag bara ha returnerat förfrågan, så att den bara körs utan ändringar i headern.

så istället för

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

Jag var tvungen att göra följande:

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

Annars blir förfrågan avlyssnad och körs aldrig eftersom den inte returneras av interceptorn. Metoden i min komponent är prenumererad på resultatet av servicemetoden och förväntar sig därför en observable, men inget returneras någonsin eftersom förfrågan blev avlyssnad och interceptorn märkte att en Authorization-header redan fanns (satt i servicen) och bestämde sig därför för att inte göra något med förfrågan.

Detta förklarar varför jag fick felet som angav att jag hade tillhandahållit undefined medan en ström (observable) förväntades på subscribe-raden i metodens komponent.

Relaterade artiklar