我正在通过课程学习角度,目前我正在学习拦截器。课程中的角度版本不是 17,但我在本地使用的版本是。因此,在第一次尝试通过类实现拦截器后,由于拦截没有发生,因此无法工作。
当我查看网络并发现我们可以创建一个拦截常量并且我们可以在 app.config.ts 中提供它时,即使这样做之后它也不起作用。所以我真的被困住了。任何帮助,将不胜感激。这是我的文件:
app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { Post } from './Post';
import { PostService } from './post-service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet, HttpClientModule, FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent implements OnInit, OnDestroy {
title = 'http-request';
postJsonUrl: string = 'https://ng-complete-guide-d77e5-default-rtdb.firebaseio.com/posts.json';
loadedPosts: Post[] = [];
isFetching = false;
error = null;
errorSubscription: Subscription;
constructor(private http: HttpClient, private postService: PostService) { }
ngOnInit() {
this.isFetching = true;
this.errorSubscription = this.postService.error.subscribe(errorMessage => {
this.error = errorMessage;
});
//things metioned in ngOnInit will load once the application is loaded
//subscribing here, heavy-lifiting in service class
this.postService.fetchPosts().subscribe(posts => {
this.isFetching = false;
this.loadedPosts = posts;
console.log(posts);
}, error => {
this.isFetching = false;
this.error = error.message;
console.log(error);
});
}
onCreatePost(postData: Post) {
this.postService.createAndStorePost(postData.title, postData.content);
}
onFetchPosts() {
this.isFetching = true;
// Send Http request
//subscribing here, heavy-lifiting in service class
this.postService.fetchPosts().subscribe(posts => {
this.isFetching = false;
this.loadedPosts = posts;
}, error => {
this.isFetching = false;
this.error = error.message;
});
}
onClearPosts() {
this.postService.deletePosts().subscribe(() => {
this.isFetching = false;
this.loadedPosts = [];
})
}
onErrorHandling() {
this.error = false;
this.isFetching = false;
}
ngOnDestroy(): void {
this.errorSubscription.unsubscribe();
}
}
auth-interceptor-service.interceptor.ts
import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptorServiceInterceptor: HttpInterceptorFn = (req, next) => {
console.log("Request is on its way");
return next(req);
};
app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient, withInterceptors, withInterceptorsFromDi } from '@angular/common/http';
import { authInterceptorServiceInterceptor } from './auth-interceptor-service.interceptor';
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes), provideHttpClient(withInterceptors([
authInterceptorServiceInterceptor
]))]
};
后期服务.ts
import { HttpClient, HttpEventType, HttpHeaders, HttpParams } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Post } from "./Post";
import { Subject, map, tap } from "rxjs";
//either provide it this way or in app.module.ts if exists
@Injectable({ providedIn: 'root' })
export class PostService {
postJsonUrl: string = 'https://ng-complete-guide-d77e5-default-rtdb.firebaseio.com/posts.json';
error = new Subject<string>();
constructor(private http: HttpClient) { }
createAndStorePost(title: string, content: string) {
const postData: Post = { title: title, content: content };
// Send Http request
console.log(postData);
this.http
.post(
this.postJsonUrl, //.json for firebase
postData,
{
observe: 'response',
//response will show the whole body
responseType : 'json'
}
)
.subscribe(responseData => {
console.log(responseData);
}, error => {
this.error.next(error.message);
});
//angular uses observables for http requests. If not subscribed, it discards that particular
//http as not important, hence no result. So do subscribe to http requests.
}
fetchPosts() {
let searchParams = new HttpParams();
searchParams = searchParams.append('print', 'pretty');
searchParams = searchParams.append('custom', 'key');
return this.http.get<{ [key: string]: Post }>(this.postJsonUrl,
{
//we can send header
headers: new HttpHeaders({'Custom-Header' : 'Hello'}),
//and params too....... two paramters
params : searchParams
})
//.pipe() does intermediate operation and returns a new obserable which can be subscribed
.pipe(map(responseData => {
const postsArray: Post[] = [];
for (const key in responseData) {
if (responseData.hasOwnProperty(key)) {
postsArray.push({ ...responseData[key], id: key });
console.log(postsArray);
}
}
return postsArray;
}));
//here we funneled our object from the pbject and added them in array
//we gonna sibscribe in component page
}
deletePosts(){
return this.http.delete(this.postJsonUrl, {
observe : 'events',
responseType : 'json'
}).pipe(tap(event => {
if(event.type == HttpEventType.Sent){
//...
}
if(event.type === HttpEventType.Response){
console.log(event);
}
}));
}
}
帖子.ts
export interface Post {
title: string;
content: string;
id?: string;
}
我尝试了所有解决方案,例如: 添加@SkipSelf,检查HttpClientModule是否仅导入一次。但没有任何效果。
在 Angular 15 之前,Angular 中有类拦截器需要注册到 apps 下的 app.module 中。然而,从版本 15 开始,使用功能拦截器,在 Angular 17 中,应该在 app.config.ts 中注册
导出const appConfig:ApplicationConfig = { 提供者:[ 提供路由器(路由), 提供HttpClient(withInterceptors([YourInterceptor])), ]};