如何从离子存储中设置离子子域常量?
How set a subdomain const in ionic from the ionic storage?
我正在构建一个用户必须在某个子域上登录的应用程序。这对每个用户来说都是不同的。因此,在登录页面上,用户使用子域、用户名和密码登录。在执行 api 调用之前,我必须将子域保存在离子存储中。这没问题,但我将如何在我的 api 服务中将该子域用作常量,因为它是异步的,不会立即给出值。
这是我在服务中的功能
startFunction(entry) {
this.storage.get('subdomain').then(
result => {
return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers}
);
}
)
}
这是我的页面组件
otherFunction(){
this.GetApi.startFunction(entry).subscribe(
result => {
console.log(result)
},
err => {
console.log(err);
});
}
但这给出了错误cannot subscribe to undefined
,如何在promise/observable中使用异步存储值。最好是一种常量,我可以将其用于 api 服务中的每个函数。
您需要return
来自startFunction
的承诺:
startFunction(entry) {
return this.storage.get('subdomain').then(result => {
// ^^^^^^
return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers};
});
}
然后使用 then
而不是 subscribe
:
otherFunction(){
this.GetApi.startFunction(entry).then(result => {
console.log(result)
}, err => {
console.log(err);
});
}
@Bergi 回答正确。但是你需要在承诺解决后订阅,因为你的承诺 returns 一个可观察的:
startFunction(entry) {
return this.storage
.get('subdomain')
.then(result => this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers});
}
并且:
otherFunction(){
this.GetApi.startFunction(entry)
.then( observable$ => observable$.subscribe( result =>
{
console.log(result)
},
err => {
console.log(err);
}))
}
我会在这里利用 HttpInterceptor
来避免获取所有 http-request 的子域。 HttpInterceptor 很棒! :D
所以你可以做什么,创建一个拦截器,正如它在你的问题中所说的那样,你在发出任何 http-request 之前设置了子域,所以假设你在发出 http 请求时总是有一个子域。
我还看到你正在设置 headers。如果 headers 对所有人都一样,你也可以在拦截器中这样做。不过我没有把它包括在这里。
所以这就是您的拦截器的样子:
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
constructor(private storage: Storage) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const obs = Observable.fromPromise(this.storage.get('subdomain'));
return obs.flatMap(data => {
console.log(data); // here should be your subdomain
// add your subdomain, and the rest of the url
const apiReq = req.clone({ url: `${data}${req.url}` });
return next.handle(apiReq);
})
}
}
这意味着,在您的请求中,忽略子域,只添加后者的一部分 url,因为我们在拦截器中添加子域:
return this.http.post(this.apiUrl, entry, { headers: HEADER.headers}
这是一个虚拟示例,我只是在拦截器的存储中设置数据,您可以在您当前正在做的地方进行操作。
注意,您不需要对有效负载进行字符串化。
StackBlitz
我正在构建一个用户必须在某个子域上登录的应用程序。这对每个用户来说都是不同的。因此,在登录页面上,用户使用子域、用户名和密码登录。在执行 api 调用之前,我必须将子域保存在离子存储中。这没问题,但我将如何在我的 api 服务中将该子域用作常量,因为它是异步的,不会立即给出值。
这是我在服务中的功能
startFunction(entry) {
this.storage.get('subdomain').then(
result => {
return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers}
);
}
)
}
这是我的页面组件
otherFunction(){
this.GetApi.startFunction(entry).subscribe(
result => {
console.log(result)
},
err => {
console.log(err);
});
}
但这给出了错误cannot subscribe to undefined
,如何在promise/observable中使用异步存储值。最好是一种常量,我可以将其用于 api 服务中的每个函数。
您需要return
来自startFunction
的承诺:
startFunction(entry) {
return this.storage.get('subdomain').then(result => {
// ^^^^^^
return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers};
});
}
然后使用 then
而不是 subscribe
:
otherFunction(){
this.GetApi.startFunction(entry).then(result => {
console.log(result)
}, err => {
console.log(err);
});
}
@Bergi 回答正确。但是你需要在承诺解决后订阅,因为你的承诺 returns 一个可观察的:
startFunction(entry) {
return this.storage
.get('subdomain')
.then(result => this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers});
}
并且:
otherFunction(){
this.GetApi.startFunction(entry)
.then( observable$ => observable$.subscribe( result =>
{
console.log(result)
},
err => {
console.log(err);
}))
}
我会在这里利用 HttpInterceptor
来避免获取所有 http-request 的子域。 HttpInterceptor 很棒! :D
所以你可以做什么,创建一个拦截器,正如它在你的问题中所说的那样,你在发出任何 http-request 之前设置了子域,所以假设你在发出 http 请求时总是有一个子域。
我还看到你正在设置 headers。如果 headers 对所有人都一样,你也可以在拦截器中这样做。不过我没有把它包括在这里。
所以这就是您的拦截器的样子:
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
constructor(private storage: Storage) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const obs = Observable.fromPromise(this.storage.get('subdomain'));
return obs.flatMap(data => {
console.log(data); // here should be your subdomain
// add your subdomain, and the rest of the url
const apiReq = req.clone({ url: `${data}${req.url}` });
return next.handle(apiReq);
})
}
}
这意味着,在您的请求中,忽略子域,只添加后者的一部分 url,因为我们在拦截器中添加子域:
return this.http.post(this.apiUrl, entry, { headers: HEADER.headers}
这是一个虚拟示例,我只是在拦截器的存储中设置数据,您可以在您当前正在做的地方进行操作。
注意,您不需要对有效负载进行字符串化。