如何将动态变量从服务传递给 http_interceptor
How to pass dynamic variable to http_interceptor from a service
我有多个 angular 项目,每个项目都有调用相同 API 的服务。
我一直在添加一个 header 来请求以确定请求是从哪个应用程序发送的。
所以我一直在尝试创建一个具有 基本服务 class 的库来设置 header 值
@Injectable({ providedIn: "root" })
export class AppbaseService {
scope: string;
constructor(@Inject(forwardRef(()=>'scope')) scope:string) {
this.scope = scope;
}
getScope():string{
return this.scope;
}
}
和一个 http 拦截器 将该动态值作为 header
附加到请求
@Injectable()
export class ScopeInterceptor implements HttpInterceptor {
constructor(private appBaseService: AppbaseService) {
}
intercept(req: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
const clonedRequest = req.clone({
headers: req.headers.append(
'Scope',
this.appBaseService.scope
)
});
return next.handle(clonedRequest);
}
}
最后一个 factory 将动态值设置为 provider
export function appValueFactory(baseService: AppbaseService) {
console.log(baseService);
return baseService.getScope();
}
但我不知道如何在模块中设置提供程序并出现以下错误,这不是很有帮助。
Uncaught Error: Can't resolve all parameters for qI: (?).
at Jt (main.js:1)
at e._getDependenciesMetadata (main.js:1)
at e._getFactoryMetadata (main.js:1)
at e.getProviderMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
有人能给我指出正确的方向吗?
谢谢。
首先,“这是做什么用的:@Inject(forwardRef(()=>'scope'))
?
在构造函数中你应该注入服务并且范围是一个字符串。
我知道 scope
是当前应用程序的字符串标识符,所以简单的解决方案是直接在拦截器中添加该字符串。
如果您希望使用服务来获取该字符串,问题将在 AppbaseService
内部,因为 scope
值是异步的(它在构造函数中填充)所以,如果您的代码尝试在创建 AppbaseService
之前调用 ScopeInterceptor
,scope
将是未定义的。
要解决此问题,请将服务 return 设为 Observable(我们假设 scopeService.getAppScope()
return 此应用的范围字符串)
export class AppbaseService {
scope = new BehaviorSubject<string>('');
constructor(private scopeService: ScopeService) {
this.scope.next(scopeService.getAppScope());
}
getScope$(): Observable<string> {
return this.scope.asObservable();
}
}
并且从拦截器使用这个异步函数并且return也是一个 Observable:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.appBaseService.getScope$().pipe(
filter(scope => !!scope),
take(1),
switchMap(scope => {
const clonedRequest = req.clone({
headers: req.headers.append('Scope',scope)
});
return next.handle(clonedRequest);
}))
}
rxjs函数解释:
filter
用于过滤未定义的值:当范围尚未定义时,不要继续管道。
take(1)
:一旦接收到值,只消耗一次observable然后完成。
switchMap
:从作用域 observable 和 returns 另一个 observable 中获取值 HttpEvent
我有多个 angular 项目,每个项目都有调用相同 API 的服务。 我一直在添加一个 header 来请求以确定请求是从哪个应用程序发送的。 所以我一直在尝试创建一个具有 基本服务 class 的库来设置 header 值
@Injectable({ providedIn: "root" })
export class AppbaseService {
scope: string;
constructor(@Inject(forwardRef(()=>'scope')) scope:string) {
this.scope = scope;
}
getScope():string{
return this.scope;
}
}
和一个 http 拦截器 将该动态值作为 header
附加到请求
@Injectable()
export class ScopeInterceptor implements HttpInterceptor {
constructor(private appBaseService: AppbaseService) {
}
intercept(req: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
const clonedRequest = req.clone({
headers: req.headers.append(
'Scope',
this.appBaseService.scope
)
});
return next.handle(clonedRequest);
}
}
最后一个 factory 将动态值设置为 provider
export function appValueFactory(baseService: AppbaseService) {
console.log(baseService);
return baseService.getScope();
}
但我不知道如何在模块中设置提供程序并出现以下错误,这不是很有帮助。
Uncaught Error: Can't resolve all parameters for qI: (?).
at Jt (main.js:1)
at e._getDependenciesMetadata (main.js:1)
at e._getFactoryMetadata (main.js:1)
at e.getProviderMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
有人能给我指出正确的方向吗?
谢谢。
首先,“这是做什么用的:@Inject(forwardRef(()=>'scope'))
?
在构造函数中你应该注入服务并且范围是一个字符串。
我知道 scope
是当前应用程序的字符串标识符,所以简单的解决方案是直接在拦截器中添加该字符串。
如果您希望使用服务来获取该字符串,问题将在 AppbaseService
内部,因为 scope
值是异步的(它在构造函数中填充)所以,如果您的代码尝试在创建 AppbaseService
之前调用 ScopeInterceptor
,scope
将是未定义的。
要解决此问题,请将服务 return 设为 Observable(我们假设 scopeService.getAppScope()
return 此应用的范围字符串)
export class AppbaseService {
scope = new BehaviorSubject<string>('');
constructor(private scopeService: ScopeService) {
this.scope.next(scopeService.getAppScope());
}
getScope$(): Observable<string> {
return this.scope.asObservable();
}
}
并且从拦截器使用这个异步函数并且return也是一个 Observable:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.appBaseService.getScope$().pipe(
filter(scope => !!scope),
take(1),
switchMap(scope => {
const clonedRequest = req.clone({
headers: req.headers.append('Scope',scope)
});
return next.handle(clonedRequest);
}))
}
rxjs函数解释:
filter
用于过滤未定义的值:当范围尚未定义时,不要继续管道。take(1)
:一旦接收到值,只消耗一次observable然后完成。switchMap
:从作用域 observable 和 returns 另一个 observable 中获取值HttpEvent