如何从离子存储中设置离子子域常量?

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