0

Я только что закончил свое приложение Login-Registration-App с Angular 2 и Firebase, но у меня есть некоторые проблемы с «правильной» обработкой ошибок

My Angular 2 App Structure выглядит так:Ловля ошибок Firebase в 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 

вся моя App работает отлично, но я теперь хочу поймать FirebaseErrors и показать его в Bootstrap Modal.

Я создал 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) 

не вызывает ошибок, он просто регистрирует ошибку в консоли.

Я также пробовал этот код из here и here:

.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."} 

к нормальному Bootstrap-режимное

Что я делаю неправильно? или что я пропустил?

+0

Вы пробовали https://ng-bootstrap.github.io/#/components/modal? Это позволяет вам легко открывать модальные сервисы. –

ответ

2

Прежде всего, в вашем auth.service.ts вы теряете контекст в своей функции catch, и именно поэтому вы получаете эту ошибку. Вы можете решить эту проблему с помощью arrow functions:

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 будет вызван.Я не как ваша служба ошибок реализуется, но один подход заключается в создании субъекта собственности, как в этом примере:

@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());' to 'this.errorService.handleError (error);' и это сработало – Blueblazer172