0

Ich habe gerade meine eigene Login-Anmelde-App mit Angular 2 und Firebase abgeschlossen, aber ich habe einige Probleme mit der "richtigen" Fehlerbehandlung

Meine Angular 2 App-Struktur sieht folgendermaßen aus:Abfangen von Firebase-Fehlern in einem Bootstrap-Modal

| app.component.css 
| app.component.html 
| app.component.ts 
| app.module.ts 
| app.routing.ts 
| index.ts 
| 
+---errors 
|  error.component.html 
|  error.component.ts 
|  error.model.ts 
|  error.service.ts 
|  
+---protected 
|  protected.component.ts 
|  protected.guard.ts 
|  
+---shared 
|  auth.service.ts 
|  header.component.ts 
|  index.ts 
|  user.interface.ts 
|  
\---unprotected 
     signin.component.ts 
     signup.component.ts 

Meine ganze App funktioniert gut, aber ich mag jetzt den FirebaseErrors fangen und es in einem Bootstrap Modal zu zeigen.

Ich habe einen errorService, ein errorModel und eine errorComponent erstellt. Ich habe versucht, folgende:

Zuerst habe ich definiert eine Fehlerklasse in meinem error.model.ts

export class Error { 
    constructor(public title: string, public message: string) {} 
} 

Dann lese ich meine eingerichtet haben error.component.ts

export class ErrorComponent implements OnInit{ 
    error: Error; 
    display = 'none'; 

    constructor(private errorService: ErrorService) {} 

    onErrorHandled() { 
     this.display = 'none'; 
    } 

    ngOnInit() { 
     this.errorService.errorOccurred.subscribe(
      (error: Error) => { 
       this.error = error; 
       this.display = 'block'; 
      } 
     ); 
    } 
} 

mit der error.component.html

<div class="backdrop" [ngStyle]="{'display': display}"></div> 
<div class="modal" tabindex="-1" role="dialog" [ngStyle]="{'display': display}"> 
    <div class="modal-dialog" role="document"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
       <button type="button" class="close" aria-label="Close" (click)="onErrorHandled()"><span aria-hidden="true">&times;</span></button> 
       <h4 class="modal-title">{{ error?.title }}</h4> 
      </div> 
      <div class="modal-body"> 
       <p>{{ error?.message }}</p> 
      </div> 
      <div class="modal-footer"> 
       <button type="button" class="btn btn-default" data-dismiss="modal" (click)="onErrorHandled()">Close</button> 
      </div> 
     </div><!-- /.modal-content --> 
    </div><!-- /.modal-dialog --> 
</div><!-- /.modal --> 

Jetzt, als ich die Fehler in auth.service.ts

declare var firebase: any; 

@Injectable() 
export class AuthService { 

    constructor(private router: Router, private errorService: ErrorService) {} 

    signupUser(user:User) { 
     firebase.auth().createUserWithEmailAndPassword(user.email, user.password) 
      .catch(function (error) { 
       this.errorService.handleError(error.json()); 
       return Observable.throw(error.json()); 
      }); 
    } 
    signinUser(user:User) { 
     firebase.auth().signInWithEmailAndPassword(user.email, user.password) 
      .catch(function (error) { 
       this.errorService.handleError(error.json()); 
       return Observable.throw(error.json()); 
      }); 
    } 
} 

die Konsole fangen wollen wirft diese Fehler:

errors_chrome_console

Ich denke, etwas falsch ist mit diesen beiden Linien:

this.errorService.handleError(error.json()); 
return Observable.throw(error.json()); 

weil

wirft keinen Fehler es nur protokolliert den Fehler in der Konsole.

Ich habe auch diesen Code aus here und here versucht:

.catch(function(error) { 
    // Handle Errors here. 
    var errorCode = error.code; 
    var errorMessage = error.message; 
    // The email of the user's account used. 
    var email = error.email; 
    // The firebase.auth.AuthCredential type that was used. 
    var credential = error.credential; 
    // ... 
} 

aber noch kein Glück.

ich tatsächlich dieses Fehlerprotokoll von der Konsole angezeigt werden soll:

{code: "auth/email-already-in-use", message: "The email address is already in use by another account."} 

zu einem normalen Bootstrap-Modal

Was mache ich falsch? oder was missverstehe ich?

+0

Haben Sie versucht https://ng-bootstrap.github.io/#/components/modal? Es ermöglicht Ihnen, Modalitäten von einem Dienst zu öffnen. –

Antwort

2

Zuerst in Ihrem auth.service.ts verlieren Sie Kontext in Ihrer Fangfunktion und deshalb erhalten Sie diesen Fehler. Sie können dies durch arrow functions mit lösen:

declare var firebase: any; 

@Injectable() 
export class AuthService { 

    constructor(private router: Router, private errorService: ErrorService) {} 

    signupUser(user:User) { 
     firebase.auth().createUserWithEmailAndPassword(user.email, user.password) 
      .catch((error) => { 
       this.errorService.handleError(error.json()); 
       return Observable.throw(error.json()); 
      }); 
    } 
    signinUser(user:User) { 
     firebase.auth().signInWithEmailAndPassword(user.email, user.password) 
      .catch((error) => { 
       this.errorService.handleError(error.json()); 
       return Observable.throw(error.json()); 
      }); 
    } 
} 

nun beim Fangen und Ihre Methode Fehler von den errorService wird aufgerufen.Ich weiß nicht, wie Sie Ihre Fehler-Dienst implementiert, aber ein Ansatz ist, ein Subject-Eigenschaft wie in diesem Beispiel einzurichten:

@Injectable() 
export class ErrorService{ 
    public errorOccurred: Subject<Error>; 

    constructor(){ 
     this.errorOccurred = new BehaviorSubject<Error>(null); 
    } 

    handleError(error) { 
     this.errorOccurred.next(error); //pass next value to subject 
    } 

} 

Mit diesem Setup können Sie Fehler bekommen jetzt in Sie Komponente Fehler:

Der einzige Nachteil bei diesem Ansatz ist, dass Sie die Fehlerkomponente in Ihrer Vorlage behalten müssen. Eine Lösung hierfür wäre, eine Komponentenfactory einzurichten und das modale nur dann in Ihre Vorlage einzufügen, wenn ein Fehler auftritt. Ich kann ein PLNKR einrichten, wenn Sie das brauchen :)

+0

danke für deine antwort :) es wäre sehr schön wenn ich ein funktionierendes code-beispiel auf plnkr sehen könnte :) danke trotzdem für deine zeit – Blueblazer172

+0

hat es endlich geklappt. Danke für die ausführliche Erklärung :) Ich musste 'this.errorService.handleError (error.json());' zu 'this.errorService.handleError (error);' und es funktionierte – Blueblazer172