From 3f8a4d78665fa07d32d7f59a6cb0a7dbc480faa7 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Tue, 15 Dec 2020 09:46:15 -0600 Subject: [PATCH] Implemented basic error handling. Login works, but we don't have a route to go to, so kinda buggy. Will cleanup in Libraries story. --- src/app/_interceptors/error.interceptor.ts | 59 ++++++++++++++++++++ src/app/app.module.ts | 2 + src/app/home/home.component.html | 22 ++++---- src/app/home/home.component.ts | 7 ++- src/app/user-login/user-login.component.html | 30 ++++++---- src/app/user-login/user-login.component.ts | 11 +++- tsconfig.json | 1 + 7 files changed, 106 insertions(+), 26 deletions(-) create mode 100644 src/app/_interceptors/error.interceptor.ts diff --git a/src/app/_interceptors/error.interceptor.ts b/src/app/_interceptors/error.interceptor.ts new file mode 100644 index 000000000..124af2783 --- /dev/null +++ b/src/app/_interceptors/error.interceptor.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor +} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { NavigationExtras, Router } from '@angular/router'; +import { ToastrService } from 'ngx-toastr'; +import { catchError } from 'rxjs/operators'; + +@Injectable() +export class ErrorInterceptor implements HttpInterceptor { + + constructor(private router: Router, private toastr: ToastrService) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request).pipe( + catchError(error => { + if (error) { + console.error('error:', error); + switch (error.status) { + case 400: + if (error.error.errors) { + // Validation error + const modalStateErrors = []; + for (const key in error.error.errors) { + if (error.error.errors[key]) { + modalStateErrors.push(error.error.errors[key]); + } + } + throw modalStateErrors.flat(); + } else { + this.toastr.error(error.statusText === 'OK' ? error.error : error.statusText, error.status); + } + break; + case 401: + // if statement is due to http/2 spec issue: https://github.com/angular/angular/issues/23334 + this.toastr.error(error.statusText === 'OK' ? 'Unauthorized' : error.statusText, error.status); + break; + case 404: + this.router.navigateByUrl('/not-found'); + break; + case 500: + const navigationExtras: NavigationExtras = {state: {error: error.error}}; + this.router.navigateByUrl('/server-error', navigationExtras); + break; + default: + this.toastr.error('Something unexpected went wrong.'); + console.log(error); + break; + } + } + return throwError(error); + }) + ); + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index fbda55d37..4478940a0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,6 +12,7 @@ import { NavHeaderComponent } from './nav-header/nav-header.component'; import { JwtInterceptor } from './_interceptors/jwt.interceptor'; import { UserLoginComponent } from './user-login/user-login.component'; import { ToastrModule } from 'ngx-toastr'; +import { ErrorInterceptor } from './_interceptors/error.interceptor'; @NgModule({ declarations: [ @@ -32,6 +33,7 @@ import { ToastrModule } from 'ngx-toastr'; }), ], providers: [ + {provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true}, {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true} ], bootstrap: [AppComponent] diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 10b55e847..7f0af61dd 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -4,20 +4,22 @@

Please create an admin account for yourself to start your reading journey.

-
- + +
+ + +
+ +
+ + +
- - - +
- + diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index 60c4e8cc0..281165878 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { MemberService } from '../member.service'; @@ -20,7 +21,7 @@ export class HomeComponent implements OnInit { password: new FormControl('', [Validators.required]) }); - constructor(public accountService: AccountService, private memberService: MemberService) { + constructor(public accountService: AccountService, private memberService: MemberService, private router: Router) { } ngOnInit(): void { @@ -37,7 +38,9 @@ export class HomeComponent implements OnInit { console.log('Registering: ', this.model); this.accountService.register(this.model).subscribe(resp => { - console.log('success', resp); + this.router.navigateByUrl('/libraries'); + }, err => { + console.log('validation errors from interceptor', err); }); } diff --git a/src/app/user-login/user-login.component.html b/src/app/user-login/user-login.component.html index aedafbd41..5f949a3e5 100644 --- a/src/app/user-login/user-login.component.html +++ b/src/app/user-login/user-login.component.html @@ -1,17 +1,23 @@ -
-
+
+

Login

-
- - - - - + +
+ + +
+ +
+ + +
+ +
+ + +
+
diff --git a/src/app/user-login/user-login.component.ts b/src/app/user-login/user-login.component.ts index de741ba9f..0b97d6e6e 100644 --- a/src/app/user-login/user-login.component.ts +++ b/src/app/user-login/user-login.component.ts @@ -10,7 +10,7 @@ import { AccountService } from '../_services/account.service'; }) export class UserLoginComponent implements OnInit { - model: any = {}; + model: any = {username: '', password: ''}; loginForm: FormGroup = new FormGroup({ username: new FormControl('', [Validators.required]), password: new FormControl('', [Validators.required]) @@ -22,12 +22,19 @@ export class UserLoginComponent implements OnInit { } login() { + this.model = {username: this.loginForm.get('username')?.value, password: this.loginForm.get('password')?.value}; this.accountService.login(this.model).subscribe(user => { - console.log('success', user); if (user) { + this.loginForm.reset(); this.router.navigateByUrl('/libraries'); } }); } + cancel() { + this.loginForm.reset(); + // Goes back to previous router state (using back in history) + //this.router.p + } + } diff --git a/tsconfig.json b/tsconfig.json index d3c1011aa..a2dc4acab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,7 @@ "target": "es2015", "module": "es2020", "lib": [ + "es2019", "es2018", "dom" ]