angular - 在 Angular 组件的其余部分之前完全加载订阅
问题描述
我需要加载一个返回公共 IP 的公共 api,以便将不同的值传递给我的服务的 http post url。但在加载其余代码之前,我需要 api 响应。我来给你展示。
_RepService.service.ts 文件:(相关部分)
getPublicIP(): Observable<string> {
return this._http.get<string>('https://api.ipify.org?format=json');
}
guardarParte(parte: NotaReparacion): Observable<JwtResponseI>{
return this._http.post<JwtResponseI>(`${this.SERVERIP}/rep/gp`,
parte).pipe(tap(
(res:JwtResponseI)=>{
if(res){console.log(res);};
},
error =>{console.log(error);}
));
}
在组件的ngOnInit 中,我有:
this._RepService.getPublicIP().subscribe(
(response) => {
var ip = JSON.stringify(response['ip']);
ip = ip.replace(/"/g,""); //regex
console.log(ip);
if (ip =="x.x.x.x") {
this._RepService.SERVERIP = "http://y.y.y.y:1000";
}else{
this._RepService.SERVERIP = "http://x.x.x.x:1000";
}
}
);
我尝试的是首先在 init 上加载 getPublicIP。所以 api 返回我的公共 IP,根据这个,不同的 IP 将用于访问数据(这是因为我需要在本地和从 Internet 访问数据)。问题是响应比代码加载慢,所以 _RepService.SERVERIP 为空,没有加载数据。如果我在 settimeout 中使用 console.log,我可以看到它正确加载。
我目前对此感到困惑,我什至不知道如何最好地解决这个问题。我应该在 app.component 中而不是在不同的组件中调用 api 吗?如何确保 api 在加载组件之前解析数据?还有其他想法可以正确解决此问题吗?
解决方案
我会避免在组件级别解析服务特定属性,而是做这样的事情。
@Injectable({
providedIn: "root"
})
export class RepService {
public get publicIP(): Promise<string> {
return (async () => {
if (!this._publicIP) {
this._publicIP = await this.fetchPublicIP();
}
return this._publicIP;
})();
}
private _publicIP: string | null = null;
constructor(private _http: HttpClient) {}
public guardarParte(parte: any): Observable<any> {
return from(this.publicIP).pipe(
switchMap(ip => this._http.post<any>(`${ip}/rep/gp`, parte))
);
}
private async fetchPublicIP(): Promise<string> {
return this._http
.get<any>("https://api.ipify.org?format=json")
.toPromise()
.then(res => `http://${res.ip}`);
}
}
采用这种方法,您可以在任何需要的地方使用guardarParte(...),如果需要,可以在后台完成获取publicIP。
推荐阅读
- python - 检查冲突/学生不能在同一课程中注册两次
- regex - 选择从可选单词(正则表达式)中搜索
- javascript - Watchify 编译一次错误然后停止
- html - asp.net core mvc中的错误路由
- google-apps-script - 根据日期将 A 列中的所有值存档/复制到 C 列
- javascript - 在请求中添加忽略 SSL 选项
- python - Django:查询 __range
- vue.js - Laravel 6.4.1 + webpack + vue + scss 动态加载
- android - 离子在应用程序中添加 android.permission.GET_ACCOUNTS 权限
- c# - 如何在 C# 中上传带有 multipart-HTML-Post 的 pdf?