Implemented basic error handling. Login works, but we don't have a route to go to, so kinda buggy. Will cleanup in Libraries story.
This commit is contained in:
parent
8fba679788
commit
3f8a4d7866
7 changed files with 106 additions and 26 deletions
59
src/app/_interceptors/error.interceptor.ts
Normal file
59
src/app/_interceptors/error.interceptor.ts
Normal file
|
|
@ -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<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
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);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -4,20 +4,22 @@
|
|||
<ng-container *ngIf="firstTimeFlow">
|
||||
<!-- NOTE: We don't need a first time user flow. We just need a simple component to register a new admin. Once registered, we can put them on admin/ route -->
|
||||
<p>Please create an admin account for yourself to start your reading journey.</p>
|
||||
<form [formGroup]="registerForm" (ngSubmit)="register()" class="form-inline mt-2 mt-md-0">
|
||||
<label>Username:
|
||||
<input class="form-control mr-sm-2" formControlName="username" type="text">
|
||||
</label>
|
||||
<form [formGroup]="registerForm" (ngSubmit)="register()">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input class="form-control" formControlName="username" type="text">
|
||||
</div>
|
||||
|
||||
<label>Password:
|
||||
<input class="form-control mr-sm-2" formControlName="password" type="password">
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input class="form-control" formControlName="password" type="password">
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary my-2 my-sm-0" type="submit">Register</button>
|
||||
<button class="btn btn-primary" type="submit">Register</button>
|
||||
</form>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!firstTimeFlow">
|
||||
<ng-container *ngIf="!firstTimeFlow && (this.accountService.currentUser$ | async) == null">
|
||||
<app-user-login></app-user-login>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
<div class="container">
|
||||
<div class="card" style="width: 18rem;">
|
||||
<div class="mx-auto" style="width: 200px;">
|
||||
<div class="card p-3" style="width: 18rem;">
|
||||
<h3 class="card-title text-center">Login</h3>
|
||||
<div class="card-text">
|
||||
<form [formGroup]="loginForm" (ngSubmit)="login()" class="form-inline mt-2 mt-md-0">
|
||||
<label>Username:
|
||||
<input class="form-control mr-sm-2" formControlName="username" type="text">
|
||||
</label>
|
||||
<form [formGroup]="loginForm" (ngSubmit)="login()">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input class="form-control" formControlName="username" type="text">
|
||||
</div>
|
||||
|
||||
<label>Password:
|
||||
<input class="form-control mr-sm-2" formControlName="password" type="password">
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input class="form-control" formControlName="password" type="password">
|
||||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-secondary mr-3" type="button" (click)="cancel()">Cancel</button>
|
||||
<button class="btn btn-primary" type="submit">Login</button>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary my-2 my-sm-0" type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"target": "es2015",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2019",
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue