Ontwikkel een Angular Component met Geavanceerde HTTP Interceptoren
description
Met deze prompt kan de gebruiker leren hoe hij HTTP interceptoren effectief inzet om netwerkverkeer te beheren en beveiliging te verbeteren binnen Angular-componenten. Het helpt problemen zoals verspreide foutafhandeling en inconsistent tokenbeheer te voorkomen, wat leidt tot beter onderhoudbare en veiliger applicaties.
prompt
Help me een Angular component te ontwikkelen die gebruikmaakt van geavanceerde HTTP interceptoren. Leg uit hoe ik interceptoren kan configureren om verzoeken te wijzigen, headers toe t ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een uitgebreide uitleg over het ontwikkelen van een Angular component die gebruikmaakt van geavanceerde HTTP interceptoren voor het beheren van verzoeken, headers, foutafhandeling en authenticatie tokens.
**Stap 1: Maak een HTTP-interceptor aan**
Een HTTP-interceptor is een Angular service die de HTTP-verzoeken kan onderscheppen en aanpassen.
```typescript
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Voeg authenticatie header toe
const authToken = localStorage.getItem('authToken');
let authReq = req;
if (authToken) {
authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`
}
});
}
// Verzoek doorsturen
return next.handle(authReq).pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
// Centrale foutafhandeling
if (error.status === 401) {
// Bijvoorbeeld: niet geauthenticeerd, logout of redirect
console.error('Niet geautoriseerd:', error.message);
// Optioneel: logout of token verversen
} else if (error.status >= 500) {
// Serverfout
console.error('Serverfout:', error.message);
} else {
// Andere fouten
console.error('HTTP fout:', error.message);
}
return throwError(() => new Error(error.message));
}
}
```
**Stap 2: Registreer de interceptor in je app module**
```typescript
import { HTTP_INTERCEPTORS } from '@angular/common/http';
@NgModule({
// ...
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class AppModule { }
```
**Stap 3: Ontwikkel de Angular component die meerdere API verzoeken doet**
De component kan de Angular HttpClient gebruiken om API calls te maken. Bijvoorbeeld:
```typescript
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-mijn-component',
templateUrl: './mijn-component.html'
})
export class MijnComponent implements OnInit {
data1: any;
data2: any;
errorMessage: string;
constructor(private http: HttpClient) { }
ngOnInit() {
this.loadData();
}
loadData() {
// Eerste API verzoek
this.http.get('/api/eerste-endpoint').subscribe({
next: (res) => this.data1 = res,
error: (err) => this.errorMessage = 'Fout bij eerste verzoek'
});
// Tweede API verzoek
this.http.get('/api/tweede-endpoint').subscribe({
next: (res) => this.data2 = res,
error: (err) => this.errorMessage = 'Fout bij tweede verzoek'
});
}
}
```
**Belangrijk:** Door de interceptor wordt automatisch de authenticatie header toegevoegd aan alle verzoeken. Je hoeft in de component zelf geen headers te beheren, tenzij je specifieke verzoeken anders wilt configureren.
**Samenvatting:**
- **Interceptor configureren:** Voeg headers toe, wijzig verzoeken, en handel fouten centraal af.
- **Authenticatiebeheer:** Bewaar tokens (bijvoorbeeld in localStorage) en voeg ze toe in de interceptor.
- **Component:** Doe meerdere API verzoeken, die automatisch worden voorzien van headers en foutafhandeling via de interceptor.
Wil je een voorbeeld van een volledige projectopzet of aanvullende functionaliteit?
provider: deepseek
model: deepseek-chat
Ik help je graag een Angular component te ontwikkelen met geavanceerde HTTP interceptoren. Hier is een complete uitleg:
## 1. HTTP Interceptor Aanmaken
Eerst maken we een interceptor voor authenticatie:
```typescript
// auth.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { catchError, switchMap, filter, take } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Token toevoegen aan alle API verzoeken
const authReq = this.addToken(req);
return next.handle(authReq).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401 && !req.url.includes('/auth/refresh')) {
return this.handle401Error(authReq, next);
}
return throwError(error);
})
);
}
private addToken(request: HttpRequest<any>): HttpRequest<any> {
const token = this.authService.getToken();
if (token) {
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
}
return request;
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap((token: any) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(token.accessToken);
return next.handle(this.addToken(request));
}),
catchError((err) => {
this.isRefreshing = false;
this.authService.logout();
return throwError(err);
})
);
} else {
return this.refreshTokenSubject.pipe(
filter(token => token != null),
take(1),
switchMap(token => {
return next.handle(this.addToken(request));
})
);
}
}
}
```
## 2. Foutafhandeling Interceptor
```typescript
// error.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ToastrService } from 'ngx-toastr';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private toastr: ToastrService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
let errorMessage = 'Er is een fout opgetreden';
if (error.error instanceof ErrorEvent) {
// Client-side error
errorMessage = `Fout: ${error.error.message}`;
} else {
// Server-side error
switch (error.status) {
case 400:
errorMessage = 'Ongeldig verzoek';
break;
case 404:
errorMessage = 'Niet gevonden';
break;
case 500:
errorMessage = 'Interne serverfout';
break;
default:
errorMessage = `Fout ${error.status}: ${error.message}`;
}
}
this.toastr.error(errorMessage, 'Fout');
return throwError(error);
})
);
}
}
```
## 3. Loading Interceptor
```typescript
// loading.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { LoadingService } from './loading.service';
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
constructor(private loadingService: LoadingService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loadingService.show();
return next.handle(req).pipe(
finalize(() => this.loadingService.hide())
);
}
}
```
## 4. Auth Service
```typescript
// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private tokenSubject: BehaviorSubject<string | null> = new BehaviorSubject<string | null>(null);
constructor(private http: HttpClient) {
// Token uit localStorage halen bij initialisatie
const savedToken = localStorage.getItem('authToken');
this.tokenSubject.next(savedToken);
}
getToken(): string | null {
return this.tokenSubject.value;
}
setToken(token: string): void {
localStorage.setItem('authToken', token);
this.tokenSubject.next(token);
}
refreshToken(): Observable<any> {
return this.http.post('/api/auth/refresh', {});
}
logout(): void {
localStorage.removeItem('authToken');
this.tokenSubject.next(null);
}
}
```
## 5. Component met Meerdere API Verzoeken
```typescript
// api-data.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin } from 'rxjs';
interface User {
id: number;
name: string;
email: string;
}
interface Product {
id: number;
name: string;
price: number;
}
@Component({
selector: 'app-api-data',
template: `
<div *ngIf="loading">Laden...</div>
<div *ngIf="!loading">
<h3>Gebruikers</h3>
<ul>
<li *ngFor="let user of users">{{ user.name }} - {{ user.email }}</li>
</ul>
<h3>Producten</h3>
<ul>
<li *ngFor="let product of products">{{ product.name }} - €{{ product.price }}</li>
</ul>
</div>
`
})
export class ApiDataComponent implements OnInit {
users: User[] = [];
products: Product[] = [];
loading = true;
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.loadData();
}
loadData(): void {
// Meerdere parallelle API verzoeken
forkJoin({
users: this.http.get<User[]>('/api/users'),
products: this.http.get<Product[]>('/api/products')
}).subscribe({
next: (results) => {
this.users = results.users;
this.products = results.products;
this.loading = false;
},
error: (error) => {
console.error('Fout bij laden data:', error);
this.loading = false;
}
});
}
// Voorbeeld van POST verzoek met custom headers
createUser(userData: any): void {
this.http.post('/api/users', userData, {
headers: {
'Custom-Header': 'custom-value'
}
}).subscribe({
next: (response) => console.log('Gebruiker aangemaakt:', response),
error: (error) => console.error('Fout bij aanmaken gebruiker:', error)
});
}
}
```
## 6. Interceptor Configuratie in AppModule
```typescript
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ApiDataComponent } from './api-data.component';
import { AuthInterceptor } from './interceptors/auth.interceptor';
import { ErrorInterceptor } from './interceptors/error.interceptor';
import { LoadingInterceptor } from './interceptors/loading.interceptor';
@NgModule({
declarations: [
AppComponent,
ApiDataComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: LoadingInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
```
## Belangrijke Functionaliteiten:
1. **Automatische Token Toevoeging**: Elke HTTP request krijgt automatisch de Authorization header
2. **Token Refresh**: Automatische token vernieuwing bij 401 errors
3. **Centrale Foutafhandeling**: Uniforme error handling voor alle API verzoeken
4. **Loading State**: Automatische loading indicator voor alle requests
5. **Parallelle Requests**: Gebruik van `forkJoin` voor meerdere simultane API calls
De interceptors werken op volgorde van registratie en worden automatisch toegepast op alle HTTP verzoeken in je applicatie.