Added Toastr
This commit is contained in:
parent
60c60b24fe
commit
b1884450ca
@ -29,6 +29,7 @@
|
||||
],
|
||||
"styles": [
|
||||
"./node_modules/font-awesome/css/font-awesome.css",
|
||||
"./node_modules/ngx-toastr/toastr.css",
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
|
22
client/package-lock.json
generated
22
client/package-lock.json
generated
@ -19,6 +19,7 @@
|
||||
"bootstrap": "^5.1.3",
|
||||
"font-awesome": "^4.7.0",
|
||||
"ngx-bootstrap": "^8.0.0",
|
||||
"ngx-toastr": "^14.3.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
@ -7974,6 +7975,19 @@
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-toastr": {
|
||||
"version": "14.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-14.3.0.tgz",
|
||||
"integrity": "sha512-d8j/sOr60w5U7rGlcKQ0Ff4u+m2NzhqU5ZdJXn7QW3aR3Zf/rY7/Fd14BmUindTOWVr2NeTYcQXCjLpir0ldpA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0-0",
|
||||
"@angular/core": ">=12.0.0-0",
|
||||
"@angular/platform-browser": ">=12.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/nice-napi": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||
@ -17534,6 +17548,14 @@
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"ngx-toastr": {
|
||||
"version": "14.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-14.3.0.tgz",
|
||||
"integrity": "sha512-d8j/sOr60w5U7rGlcKQ0Ff4u+m2NzhqU5ZdJXn7QW3aR3Zf/rY7/Fd14BmUindTOWVr2NeTYcQXCjLpir0ldpA==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"nice-napi": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||
|
@ -21,6 +21,7 @@
|
||||
"bootstrap": "^5.1.3",
|
||||
"font-awesome": "^4.7.0",
|
||||
"ngx-bootstrap": "^8.0.0",
|
||||
"ngx-toastr": "^14.3.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
@ -39,4 +40,4 @@
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.6.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { NotFoundComponent } from './core/not-found/not-found.component';
|
||||
import { ServerErrorComponent } from './core/server-error/server-error.component';
|
||||
import { TestErrorComponent } from './core/test-error/test-error.component';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import { ProductDetailsComponent } from './shop/product-details/product-details.component';
|
||||
import { ShopComponent } from './shop/shop.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: HomeComponent},
|
||||
{path: 'test-error', component: TestErrorComponent},
|
||||
{path: 'server-error', component: ServerErrorComponent},
|
||||
{path: 'not-found', component: NotFoundComponent},
|
||||
{path: 'shop', loadChildren: ()=> import('./shop/shop.module').then(mod => mod.ShopModule)},
|
||||
{path: '**', redirectTo: '', pathMatch: 'full'}
|
||||
];
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
@ -8,6 +8,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { CoreModule } from './core/core.module';
|
||||
import { ShopModule } from './shop/shop.module';
|
||||
import { HomeModule } from './home/home.module';
|
||||
import { ErrorInterceptor } from './core/interceptors/error.interceptor';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -21,7 +22,9 @@ import { HomeModule } from './home/home.module';
|
||||
CoreModule,
|
||||
HomeModule
|
||||
],
|
||||
providers: [],
|
||||
providers: [
|
||||
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true}
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
@ -2,14 +2,22 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NavBarComponent } from './nav-bar/nav-bar.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TestErrorComponent } from './test-error/test-error.component';
|
||||
import { NotFoundComponent } from './not-found/not-found.component';
|
||||
import { ServerErrorComponent } from './server-error/server-error.component';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [NavBarComponent],
|
||||
declarations: [NavBarComponent, TestErrorComponent, NotFoundComponent, ServerErrorComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule
|
||||
RouterModule,
|
||||
ToastrModule.forRoot({
|
||||
positionClass: 'toast-bottom-right',
|
||||
preventDuplicates: true
|
||||
})
|
||||
],
|
||||
exports: [NavBarComponent]
|
||||
})
|
||||
|
42
client/src/app/core/interceptors/error.interceptor.ts
Normal file
42
client/src/app/core/interceptors/error.interceptor.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
HttpRequest,
|
||||
HttpHandler,
|
||||
HttpEvent,
|
||||
HttpInterceptor
|
||||
} from '@angular/common/http';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
@Injectable()
|
||||
export class ErrorInterceptor implements HttpInterceptor {
|
||||
|
||||
constructor(private router: Router, private toastr: ToastrService) {}
|
||||
|
||||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
return next.handle(request).pipe(
|
||||
catchError(error => {
|
||||
if (error){
|
||||
|
||||
if (error.status === 400){
|
||||
this.toastr.error(error.error.message, error.error.statusCode);
|
||||
}
|
||||
|
||||
if (error.status === 401){
|
||||
this.toastr.error(error.error.message, error.error.statusCode);
|
||||
}
|
||||
|
||||
if (error.status === 404){
|
||||
this.router.navigateByUrl('/not-found');
|
||||
}
|
||||
|
||||
if (error.status === 500){
|
||||
this.router.navigateByUrl('/server-error');
|
||||
}
|
||||
}
|
||||
return throwError(() => new Error(error));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<nav class="me-3 my-md-0 mr-md-3 text-uppercase" style="font-size: larger;">
|
||||
<a class="me-3 py-2" [routerLink]="['/']" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">Home</a>
|
||||
<a class="me-3 py-2" routerLink="/shop" routerLinkActive="active">Shop</a>
|
||||
<a class="me-3 py-2">Contact</a>
|
||||
<a class="me-3 py-2" routerLink="/test-error" routerLinkActive="active">Errors</a>
|
||||
</nav>
|
||||
<div class="d-flex align-items-center">
|
||||
<a class="position-relative">
|
||||
|
3
client/src/app/core/not-found/not-found.component.html
Normal file
3
client/src/app/core/not-found/not-found.component.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div class="container mt-5">
|
||||
<h1>404 Not Found</h1>
|
||||
</div>
|
15
client/src/app/core/not-found/not-found.component.ts
Normal file
15
client/src/app/core/not-found/not-found.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-found',
|
||||
templateUrl: './not-found.component.html',
|
||||
styleUrls: ['./not-found.component.scss']
|
||||
})
|
||||
export class NotFoundComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<div class="container mt-5">
|
||||
<h1>Internal Server Error</h1>
|
||||
</div>
|
15
client/src/app/core/server-error/server-error.component.ts
Normal file
15
client/src/app/core/server-error/server-error.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-server-error',
|
||||
templateUrl: './server-error.component.html',
|
||||
styleUrls: ['./server-error.component.scss']
|
||||
})
|
||||
export class ServerErrorComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
6
client/src/app/core/test-error/test-error.component.html
Normal file
6
client/src/app/core/test-error/test-error.component.html
Normal file
@ -0,0 +1,6 @@
|
||||
<div class="container mt-5">
|
||||
<button (click)="get500Error()" class="btn btn-outline-primary me-3">Test 500 Error</button>
|
||||
<button (click)="get404Error()" class="btn btn-outline-primary me-3">Test 404 Error</button>
|
||||
<button (click)="get400Error()" class="btn btn-outline-primary me-3">Test 400 Error</button>
|
||||
<button (click)="get400ValidationError()" class="btn btn-outline-primary me-3">Test 400 Validation Error</button>
|
||||
</div>
|
58
client/src/app/core/test-error/test-error.component.ts
Normal file
58
client/src/app/core/test-error/test-error.component.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-test-error',
|
||||
templateUrl: './test-error.component.html',
|
||||
styleUrls: ['./test-error.component.scss']
|
||||
})
|
||||
export class TestErrorComponent implements OnInit {
|
||||
baseURL = environment.apiUrl;
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
get404Error(){
|
||||
this.http.get(this.baseURL + 'products/42').subscribe(
|
||||
{
|
||||
next: (response) => { console.log(response); },
|
||||
error: (e: any) => { console.log(e); },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get500Error(){
|
||||
this.http.get(this.baseURL + 'buggy/servererror').subscribe(
|
||||
{
|
||||
next: (response) => { console.log(response); },
|
||||
error: (e: any) => { console.log(e); },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get400Error(){
|
||||
this.http.get(this.baseURL + 'buggy/badrequest').subscribe(
|
||||
{
|
||||
next: (response) => { console.log(response); },
|
||||
error: (e: any) => { console.log(e); },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get400ValidationError(){
|
||||
this.http.get(this.baseURL + 'products/five').subscribe(
|
||||
{
|
||||
next: (response) => { console.log(response); },
|
||||
error: (e: any) => { console.log(e); },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,8 @@
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
production: false,
|
||||
apiUrl: 'https://localhost:5001/api/'
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user