0

我剛剛完成了我自己的Angular 2和Firebase的登錄註冊應用程序,但是我遇到了一些問題,「正確」錯誤處理

我的Angular 2應用程序結構如下所示:在Bootstrap-Modal中捕獲Firebase錯誤

| 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 

我的整個應用程序工作正常,但我現在想抓住FirebaseErrors並將其顯示在Bootstrap模式中。

我創建了一個errorService,一個errorModel和一個errorComponent。我嘗試以下操作:

首先我在error.model.ts定義錯誤類

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

,我已經建立了我的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'; 
      } 
     ); 
    } 
} 

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

現在,當我要趕在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()); 
      }); 
    } 
} 

錯誤控制檯拋出這些錯誤:

errors_chrome_console

我覺得有什麼不妥這兩行:

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

因爲

console.log(error) 

拋出錯誤,它只是在控制檯中記錄錯誤。

我也試過這個代碼herehere

.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; 
    // ... 
} 

但仍沒有運氣。

其實我是想表明從控制檯此錯誤日誌:

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

到正常的引導模態

我在做什麼錯?或者我誤解了什麼?

+0

你有沒有試過https://ng-bootstrap.github.io/#/components/modal?它允許您輕鬆打開服務中的模式。 –

回答

2

首先在你的auth.service.ts你失去了你的catch函數的上下文,這就是爲什麼你會得到這個錯誤。捕獲在

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

現在和錯誤的方法從errorService將調用:您可以通過使用arrow functions解決這個問題。我怎麼沒有你的錯誤的服務實現,但一種方法是在這個例子中設置一個主題屬性,如:

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

} 

有了這個設置,你將能夠立即得到錯誤到你錯誤組件:

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

    constructor(private errorService: ErrorService) {} 

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

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

這種方法的唯一缺點是您需要將錯誤組件保留在您的模板中。解決方案是設置一個組件工廠,並只在發生錯誤時纔將模型注入模板。我可以設置一個plnkr,如果你需要的話:)

+0

感謝您的回答:)這將是非常好的,如果我可以看到一個工作代碼示例plnkr :)謝謝反正你的時間 – Blueblazer172

+0

它終於奏效。感謝您的詳細解釋:)我不得不將'this.errorService.handleError(error.json());''this.errorService.handleError(error);'它工作 – Blueblazer172