wake-up-neo.net

Angular 4 - Fehler bei der HTTP-Anforderung: Sie haben "undefined" angegeben, wo ein Stream erwartet wurde

Beim Versuch, eine HTTP-Post-Anforderung auszuführen, erhalte ich die folgende Fehlermeldung:

auth.service.ts? c694: 156 Etwas ist fehlgeschlagen, als ein neues .__ angefordert wurde. Kennwort, Fehlermeldung: Sie haben 'undefined' angegeben, wo ein Stream .__ war. erwartet. Sie können ein Observable, Promise, Array oder Iterable bereitstellen.

Der HTTP-Anforderung wird eine andere vorangestellt, die einwandfrei funktioniert.

Meine Komponente, die den Dienst anruft:

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

Die Servicemethode, die den Fehler auslöst:

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

Immer wenn ich eine E-Mail in das Formular eingebe und absende, was wiederum die requestNewPassword-Methode der Komponente auslöst, erhalte ich den oben genannten Fehler vom Dienst.

Der Header und die E-Mail werden korrekt protokolliert. Ich glaube nicht, dass die Daten, die ich bereitstelle, mit irgendetwas zu tun haben.

Da ich keine Ahnung habe, wie ich das debuggen sollte, dachte ich, es wäre eine gute Idee, dies als Frage auf dieser unglaublichen Plattform zu posten.

Danke im Voraus!

Update

Ich habe den Code in meiner Komponente minimiert, um das Problem einzugrenzen, indem die beiden HTTP-Anforderungen nicht verkettet, sondern nur die zweite aufgerufen wird, die Probleme verursacht.

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

Ich bekomme jetzt eine vollständige Stapelverfolgung:

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)

Da dies die HTML-Datei erwähnt, werde ich auch den HTML-Code angeben:

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

Nach einer großen Anstrengung ist es mir gelungen, das Problem zu lokalisieren und zu beheben. Das Problem war, dass ich einen Berechtigungs-Interceptor habe, der jede Anforderung abfängt, einen Berechtigungs-Header mit einem Benutzerzugriffstoken hinzuzufügen.

Da für den Anruf, den ich versuchte, kein Benutzerzugriffstoken erforderlich war, sondern ein Anwendungszugriffstoken (als Anwendung für öffentliche HTTP-Anforderungen wie Registrieren, Kennwort vergessen usw.), habe ich mich entschlossen, den Anruf zu verketten, um Zugriff auf die Anwendung zu erhalten Token und den Anruf für das vergessene Kennwort. Übergeben Sie einfach das abgerufene Zugriffstoken für die Anwendung an die Methode für vergessenes Kennwort in meinem Dienst und setzen Sie es dort in den Berechtigungsheader. Dieser Code war alles in Ordnung. Das Problem war, dass ich den Interceptor bearbeitet hatte, um zu überprüfen, ob ein Berechtigungsheader vorhanden war und wenn nichts getan wurde, und dies war die Ursache des Fehlers. 

Anstatt nichts zu tun, hätte ich die Anfrage nur zurückgeben müssen, damit sie nur ohne Änderungen am Header ausgeführt wird.

also statt

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

Ich musste folgendes tun:

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

Andernfalls wird die Anforderung abgefangen und wird nicht ausgeführt, da sie vom Abfangjäger nicht zurückgegeben wird. Die Methode in meiner Komponente ist für das Ergebnis der Servicemethode abonniert und erwartet daher ein Beobachtbares, es wird jedoch nichts zurückgegeben, da die Anforderung abgefangen wurde und der Interceptor feststellte, dass bereits ein Berechtigungsheader vorhanden war (im Dienst festgelegt). Also entschied ich mich, nichts mit der Anfrage zu tun.

Dies erklärt, warum ich die Fehlermeldung erhalten habe, dass ich undefined angegeben habe, während ein Stream (beobachtbar) in der Subscribe-Zeile in der Methode meiner Komponente erwartet wurde.

14
DennisN

Ich hatte ein sehr ähnliches Problem. Es wurde auch ein Problem mit einem HTTP-Interceptor. Ich hatte eine automatische Deserialisierungsfunktion, die für alle Antworten mit einem bestimmten API-Endpunktmuster ausgeführt wurde. Antworten, bei denen es sich nicht um Fälle von HTTPResponse handelte, wurden letztendlich verzehrt. Hinzufügen einer else-Anweisung, die die Antwort unangetastet zurückgab, wenn keine Instanz von HTTPResponse das Problem für mich löst

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

(Der Code zur Fehlerbehandlung wurde zur besseren Übersichtlichkeit entfernt.)

0