如何在 HttpInterceptor 中使用 NGXS 存储的值?
how to use value from NGXS store in HttpInterceptor?
我是 Angular 的新手。我正在使用 Angular 6 和 NGXS 进行状态管理。
我的 NGXS 商店有一个 user
reducer,它的接口是
/* src/app/store/models/user.model.ts */
export interface User {
serverToken? : string;
// and other unrelated stuff
}
我想在 Authorization
header 中使用 serverToken
HttpInterceptor
。
这是我当前的 HttpInterceptor
个代码
import {Store, Select} from '@ngxs/store';
import {Injectable} from '@angular/core';
import {HttpInterceptor, HttpHandler, HttpRequest, HttpEvent} from '@angular/common/http';
import {Observable} from 'rxjs';
import {User} from '../store/models/user.model';
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor(private store : Store) {}
@Select()user$ : Observable < User >;
intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
let options = {
url: `https://base-url.com/api/${req.url}`
};
const serverToken = '???';
if (serverToken) // if not empty
options = {
...options,
headers: req
.headers
.set('Authorization', `JWT ${serverToken}`)
}
const duplicate = req.clone(options);
return next.handle(duplicate);
}
}
所以我的问题是:如何正确优雅地使用 user$
observable 来获取 serverToken
并在 HttpInterceptor
中使用它 if serverToken
不为空?
我最终使用了 NGXS 的 snapshot 功能。不确定这是否是最好的方法。 (快照功能在NGXS中可用,但在NGRX中不可用。我不知道如何在NGRX中解决这个问题)
在user.state.ts
@State < User > ({name: "user", defaults: {}})
export class UserState {
// ...
@Selector()
static serverToken(user : User) {
return user.serverToken || '';
}
}
在HttpInterceptor
const serverToken = this
.store
.selectSnapshot(UserState.serverToken);
如果您更喜欢 "observable" 的方法,请尝试类似的方法:
intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
return this.serverToken$.pipe(
take(1),
concatMap(serverToken => {
if (serverToken) {
options = {
...options,
headers: req.headers.set('Authorization', `JWT ${serverToken}`)
}
const duplicate = req.clone(options);
return next.handle(duplicate)
} else {
// next() without changing req
return next(req)
}
}
)
}
您还需要定义一个 @Selector
returns 用户令牌和 @Select
来自拦截器的 class。
注意:我不熟悉 HTTP 拦截器,只是根据我在 intercept()
.
的签名中看到的内容应用链接 RxJS 可观察对象的概念
我是 Angular 的新手。我正在使用 Angular 6 和 NGXS 进行状态管理。
我的 NGXS 商店有一个 user
reducer,它的接口是
/* src/app/store/models/user.model.ts */
export interface User {
serverToken? : string;
// and other unrelated stuff
}
我想在 Authorization
header 中使用 serverToken
HttpInterceptor
。
这是我当前的 HttpInterceptor
个代码
import {Store, Select} from '@ngxs/store';
import {Injectable} from '@angular/core';
import {HttpInterceptor, HttpHandler, HttpRequest, HttpEvent} from '@angular/common/http';
import {Observable} from 'rxjs';
import {User} from '../store/models/user.model';
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor(private store : Store) {}
@Select()user$ : Observable < User >;
intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
let options = {
url: `https://base-url.com/api/${req.url}`
};
const serverToken = '???';
if (serverToken) // if not empty
options = {
...options,
headers: req
.headers
.set('Authorization', `JWT ${serverToken}`)
}
const duplicate = req.clone(options);
return next.handle(duplicate);
}
}
所以我的问题是:如何正确优雅地使用 user$
observable 来获取 serverToken
并在 HttpInterceptor
中使用它 if serverToken
不为空?
我最终使用了 NGXS 的 snapshot 功能。不确定这是否是最好的方法。 (快照功能在NGXS中可用,但在NGRX中不可用。我不知道如何在NGRX中解决这个问题)
在user.state.ts
@State < User > ({name: "user", defaults: {}})
export class UserState {
// ...
@Selector()
static serverToken(user : User) {
return user.serverToken || '';
}
}
在HttpInterceptor
const serverToken = this
.store
.selectSnapshot(UserState.serverToken);
如果您更喜欢 "observable" 的方法,请尝试类似的方法:
intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
return this.serverToken$.pipe(
take(1),
concatMap(serverToken => {
if (serverToken) {
options = {
...options,
headers: req.headers.set('Authorization', `JWT ${serverToken}`)
}
const duplicate = req.clone(options);
return next.handle(duplicate)
} else {
// next() without changing req
return next(req)
}
}
)
}
您还需要定义一个 @Selector
returns 用户令牌和 @Select
来自拦截器的 class。
注意:我不熟悉 HTTP 拦截器,只是根据我在 intercept()
.