Jeśli tworzysz aplikację przy użyciu AngularJS, prawdopodobnie wiesz o istnieniu interceptorów HTTP. Jednak te interceptory HTTP nie były dostępne w Angularze aż do wersji 4.3. W tym samouczku użyjemy interceptorów w Angularze do obsługi żądań i odpowiedzi HTTP oraz przetwarzania błędów.
Wymagania wstępne
Angular aplikacje używają środowiska uruchomieniowego Node.js. Aby ukończyć ten samouczek, musisz mieć zainstalowany Node.js na swoim komputerze. Na szczęście Node.js jest dość łatwy w instalacji. Mamy kompletny przewodnik na temat Jak zainstalować Node.js na Ubuntu 18.04 tutaj.
Dodatkowo, pomocna będzie znajomość Angulara oraz umiejętność korzystania z Angular CLI do budowania aplikacji Angular. Będziemy używać Node v8.12.0 i npm v6.4.1.
Krok 1: Utwórz aplikację Angular
Na początek utwórzmy nową aplikację Angular za pomocą Angular CLI. Nazwiemy naszą aplikację Angular-Interceptor. Uruchom poniższe polecenie, aby utworzyć aplikację:
|
1 |
npx @angular/cli@7.0.6 new Angular-Interceptor |
Zostaniesz poproszony o dokonanie kilku wyborów. Wprowadź wartości domyślne i przejdź dalej:

Następnie przejdź do katalogu aplikacji i uruchom poniższe polecenie, aby uruchomić aplikację:
|
1 |
npx ng serve --open |

Następnie otwórz http://localhost:4200 w przeglądarce, aby zobaczyć aplikację. Skonfigurowałeś właśnie podstawową aplikację Angular.
Krok 2: Ostyluj aplikację Angular
Tutaj ostylujemy naszą aplikację Angular za pomocą Angular Material. Aby zainstalować Angular Material w swoim projekcie, uruchom poniższe polecenie:
|
1 |
npm install --save @angular/material@7.0.4 @angular/cdk@7.0.4 @angular/animations@7.0.4 |
To zainstaluje @angular/material, @angular/cdk, oraz @angular/animation w Twoim projekcie. Następnie skonfigurujemy animację w projekcie. Dodaj BrowserAnimationsModule w pliku src/app/module.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @NgModule({ ... imports: [ ... BrowserAnimationsModule ], ... }) export class AppModule { } |
Będziemy używać komponentu Dialog z Angular Material. Aby użyć komponentu Dialog, musimy zaimportować MatDialogModule w pliku src/app/app.module.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { MatDialogModule } from '@angular/material'; @NgModule({ ... imports: [ ... MatDialogModule ], ... }) export class AppModule { } |
Aby uczynić interfejs użytkownika bardziej atrakcyjnym, dodajmy indigo-pink.css do pliku styles.scss :
|
1 |
@import "~@angular/material/prebuilt-themes/indigo-pink.css"; |
Krok 3: Zbuduj swój interceptor Angular
W folderze app utworzymy nowy folder o nazwie interceptor. Wewnątrz tego nowo utworzonego folderu utwórz nowy plik httpconfig.interceptor.ts .
Musimy zaimportować pewne zależności w naszym pliku httpconfig.interceptor.ts, aby nasz interceptor działał. Te zależności to HttpInterceptor, HttpRequest, HttpResponse, oraz HttpHandler, HttpEvent, HttpErrorResponse.
Nasz plik httpconfig.interceptor.ts po imporcie będzie wyglądał następująco:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; |
Następnie utwórz klasę HttpConfigInterceptor i zaimplementuj interfejs HttpInterceptor. Oto przykład:
|
1 2 3 4 5 6 7 |
@Injectable() export class HttpConfigInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // ... } } |
Dodaj poniższy kod do pliku httpconfig.interceptor.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
... @Injectable() export class HttpConfigInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const token: string = localStorage.getItem('token'); if (token) { request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token) }); } if (!request.headers.has('Content-Type')) { request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') }); } request = request.clone({ headers: request.headers.set('Accept', 'application/json') }); return next.handle(request).pipe( map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { console.log('event--->>>', event); } return event; })); } } |
Aby to zadziałało, musimy zaimportować httpconfig.interceptor.ts w naszym pliku app.module.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; ... import { HttpConfigInterceptor } from './interceptor/httpconfig.interceptor'; @NgModule({ ... imports: [ ... HttpClientModule ], ... }) |
Dodaj HttpConfigInterceptor do sekcji providers. Ustawimy multi: true na true, aby obsłużyć wiele interceptorów:
|
1 2 3 4 5 6 7 8 9 10 |
... @NgModule({ ... providers: [ ... { provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true } ], ... }) ... |
W kolejnej sekcji utworzymy naszą usługę do obsługi błędów.
Step 4: Service for Handling Errors
Tutaj napiszemy kod do obsługi błędów. Będziemy musieli przechwytywać błędy i odpowiednio wyświetlać je użytkownikom końcowym. W skrócie, poniżej przedstawiono kroki, które wykonamy:
- Utwórz folder o nazwie error-dialog w folderze app .
- Utwórz usługę do obsługi błędów o nazwie errorDialogService w pliku o nazwie errordialog.service.ts.
- Dodaj poniższy kod w pliku errordialog.service.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { Injectable } from '@angular/core'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { ErrorDialogComponent } from './errordialog.component'; @Injectable() export class ErrorDialogService { public isDialogOpen: Boolean = false; constructor(public dialog: MatDialog) { } openDialog(data): any { if (this.isDialogOpen) { return false; } this.isDialogOpen = true; const dialogRef = this.dialog.open(ErrorDialogComponent, { width: '300px', data: data }); dialogRef.afterClosed().subscribe(result => { console.log('Okno dialogowe zostało zamknięte'); this.isDialogOpen = false; let animal; animal = result; }); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material'; @Component({ selector: 'app-root', templateUrl: './errordialog.component.html' }) export class ErrorDialogComponent { title = 'Angular-Interceptor'; constructor(@Inject(MAT_DIALOG_DATA) public data: string) {} } |
|
1 2 3 4 5 6 7 8 9 10 |
<div> <div> <p> Powód: {{data.reason}} </p> <p> Stan: {{data.status}} </p> </div> </div> |
Podsumowując, poniżej wymieniono poszczególne kroki:
- Zacznij od zaimportowania errordialog.service.
- Następnie dodamy konstruktor dla errorDialogService.
- Dodamy również kod do obsługi odpowiedzi o błędzie za pomocą catchError oraz throwError.
- Zaimportuj errordialog.service oraz errordialog.component do AppModule.
Po wprowadzeniu zmian zmodyfikowane zostaną dwa pliki: app.module.ts i httpconfig.interceptor.ts:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... import { ErrorDialogComponent } from './error-dialog/errordialog.component'; ... import { ErrorDialogService } from './error-dialog/errordialog.service'; ... @NgModule({ ... declarations: [ ... ErrorDialogComponent ], ... providers: [ ... ErrorDialogService ], entryComponents: [ErrorDialogComponent], }) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
... import { ErrorDialogService } from '../error-dialog/errordialog.service'; ... @Injectable() export class HttpConfigInterceptor implements HttpInterceptor { constructor(public errorDialogService: ErrorDialogService) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { ... return next.handle(request).pipe( map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { console.log('event--->>>', event); } return event; }), catchError((error: HttpErrorResponse) => { let data = {}; data = { reason: error && error.error && error.error.reason ? error.error.reason : '', status: error.status }; this.errorDialogService.openDialog(data); return throwError(error); })); } } |
Krok 5: Tworzenie przykładowych usług
W tym kroku utworzymy dwie przykładowe usługi:
- API logowania
- API szczegółów klienta
Utwórz nowy folder o nazwie services w folderze src . Następnie wewnątrz tego nowo utworzonego folderu utwórz nowy plik o nazwie login.service.ts, i dodaj dwie funkcje:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable() export class LoginService { constructor(private http: HttpClient) { } login(data) { data = { email: 'admin', password: 'admin' }; return this.http.post('http://localhost:3070/api/login', data); } getCustomerDetails() { return this.http.get('http://localhost:3070/customers/details'); } } |
Krok 6: Wywoływanie usługi klienta HTTP
Na koniec dotarliśmy do ostatniej części naszego samouczka. Będziemy wywoływać naszą usługę HTTP z pliku app.component.ts. Dodaj dwie funkcje LoginService do pliku app.component.ts. Wywołaj API logowania przy onload, a customers/details przy onclick:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { Component } from '@angular/core'; import { LoginService } from './services/login.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'Angular-Interceptor'; constructor(public loginService: LoginService) { this.loginService.login({}).subscribe(data => { console.log(data); }); } getCustomerDetails() { this.loginService.getCustomerDetails().subscribe((data) => { console.log('----->>>', data); }); } } |
Teraz musimy dodać element interfejsu użytkownika w app.component.html, aby użytkownik mógł go kliknąć:
|
1 |
<h2 (click)="getCustomerDetails()">Pobierz dane klienta</h2> |
Aby zakończyć, musisz dołączyć LoginService do providers w AppModule:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
... import { LoginService } from './services/login.service'; ... @NgModule({ ... providers: [ ... LoginService ] ... }) |
Poniżej znajduje się zrzut ekranu okna dialogowego obsługi błędów:

Podsumowanie
W tym samouczku dowiedzieliśmy się, jak obsługiwać żądania i odpowiedzi HTTP za pomocą interceptorów Angulara. Dowiedzieliśmy się również, jak obsługiwać błędy za pomocą okna dialogowego w Angular Material.
Aplikacje Angular używają Node.js jako środowiska uruchomieniowego. Jeśli chcesz dowiedzieć się więcej o Node.js i o tym, jak wdrażać aplikacje Node.js za pomocą Dockera, zapoznaj się z naszym poradnikiem Jak wdrożyć aplikację Node.js (Express.js) za pomocą Dockera na Ubuntu 20.04. Możesz również zapoznać się z Jak wykonywać zadania produkcyjne na Ubuntu 20.04 z Node.js oraz Instalacja Node.js na CentOS 8: kompletny przewodnik.
Miłego kodowania!
Komentarze
Brak komentarzy. Bądź pierwszy.