拦截器在 Angular 17 中不进行拦截

问题描述 投票:0回答:1

我正在通过课程学习角度,目前我正在学习拦截器。课程中的角度版本不是 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 angularjs angular-http angular-http-interceptors angular-httpclient-interceptors
1个回答
0
投票

在 Angular 15 之前,Angular 中有类拦截器需要注册到 apps 下的 app.module 中。然而,从版本 15 开始,使用功能拦截器,在 Angular 17 中,应该在 app.config.ts 中注册

导出const appConfig:ApplicationConfig = { 提供者:[ 提供路由器(路由), 提供HttpClient(withInterceptors([YourInterceptor])), ]};

© www.soinside.com 2019 - 2024. All rights reserved.