api - Angular 2 Observable emit/error-funktioner ignoreras efter att fel-funktionen har anropats en gång


Jag har en API-inloggningstjänst som använder en HTTP-tjänst för att utföra en inloggningslogik (LoginApiService, login-api.service.ts):

login(data: LoginCredentials): Observable<LoginResult> {
  let body = JSON.stringify( data );
  let headers = new Headers({ 'Content-Type': 'application/json' });
  let options = new RequestOptions({ headers: headers });

  return this.http.post(`${this.getBaseUrl()}/login`, body, options)
                  .map(this.extractData)
                  .catch(function(error: Response){
                    return Observable.throw(error); // IF YOU TRY TO LOGIN WITH WRONG CREDENTIALS, AN ERROR WILL BE THROWN
                  });
}

Denna tjänst används i en global tjänsteklass (authService, auth.service.ts):

login(data: LoginCredentials): void {
    this.api.login(data).subscribe(
    data => {
      this.isLoggedIn = true;
      this.group = data.group;
      this.Login.emit(new LoginResult(this.group)); // THE CALL OF THIS FUNCTION IS IGNORED IF THE "this.Login.error" FUNCTION HAS BEEN CALLED BEFORE
    },
    error => {
      this.Login.error(error); // THIS IS IGNORED TOO, IF IT WAS CALLED BEFORE
    }
  );
}

Komponent (LoginComponent, login.component.ts):

ngOnInit() {
  this.LoginSubscription = this.authService
    .Login
    .subscribe( // THE EVENTS ARE NOT FIRED IF THE ERROR EVENT HAS BEEN FIRED BEFORE ONCE
      data => {
        if ( this.authService.isLoggedIn ) {
          this.router.navigate(['/dashboard']);
        }
      },
      error => {
        this.handleError(error);
      }
    );
}

login() {
  this.authService.login( new LoginCredentials(this.user, this.password) );
}

Mall (login.component.html):

<div>
  <label>User: </label>
  <input [(ngModel)]="user" placeholder="user">
</div>
<div>
  <label>Password: </label>
  <input [(ngModel)]="password" placeholder="password" type="password">
</div>

<p>
  <button (click)="login()">Login</button>
</p>

Om felhändelsefunktionen för inloggningsobserverbar har kallats tidigare, kommer anrop av emit- och/eller error-funktionen efter detta att ignoreras.

  • Med korrekta inloggningsuppgifter svarar den simulerade API:n med HTTP-kod 200 och allt fungerar bra
  • Vid felaktiga autentiseringsuppgifter är HTTP-svaret 500
  • Efter att ha kallat API:et igen (med rätt eller felaktiga uppgifter) utlöses inte händelserna längre

Detta betyder: Om du använder fel inloggningsuppgifter kommer du inte att kunna försöka igen utan att ladda om sidan.

  • Är min idé att använda observables fel?

  • Varför hänger händelseströmmen sig efter att fel-funktionen har anropats en gång?

  • Kan någon ge mig en ledtråd för att lösa det här problemet (någon typ av lösning t.ex.)?

Svar #1

Detta händer eftersom du genererar ett fel i din EventEmitter. EventEmitters är i princip Observables och när dess Observer anropar error eller complete stänger det Observable. Stängda Observables kommer att sluta sända händelser enligt design.

För att lösa ditt problem, ta bort this.Login.error(error); i LoginComponent, så att du inte stänger den EventEmitter. Försök att ersätta det med logik för att tala om för användaren att inloggningsuppgifterna är fel eller något annat meddelande för att beskriva felet.