【问题标题】:Property 'subscribe' does not exist on type 'Promise'“承诺”类型上不存在属性“订阅”
【发布时间】:2017-10-13 12:11:09
【问题描述】:

我仍然对 rxjs 的工作原理感到困惑。

我正在构建一个 Ionic 应用程序,该应用程序向我的服务器发出请求并需要 json。我已经成功地订阅了 http.post 并获得了我需要的数据。

但是现在我的问题是我需要在从 Storage 获得的 http 请求中传递一个身份验证令牌。这是一个问题,因为在调用 http.post 请求之前,我需要等到存储准备好并从中获取我的令牌值。

这是我试图获取我的 json 数据的地方

getPlanograms() {

    //API URL
    let requestURL = 'https://myapiurlhere';
    let headers = new Headers({'Content-Type': 'application/json'});

    return this.storage.ready().then(() => {

        return this.storage.get('id_token').then((val) => {

            headers.append('Authorization', 'Bearer ' + this.authCredentials.token);
            let options = new RequestOptions({headers: headers});
            return this.http.post(requestURL, {}, options)
                .map(response => <Planogram[]>response.json());

        })
    });
}

从这里调用

 ionViewDidLoad (){
    this.merchandisingDataService.getPlanograms()
        .subscribe(Planogram => this.planograms = Planogram);
}

但是,当我尝试这样做时,我收到以下错误

“Promise”类型上不存在“订阅”属性。

实现我的目标的最佳方式是什么?

【问题讨论】:

  • getPlanograms() 返回一个Promise。你不能subscribe 承诺。你可以 then promises 和 subscribe 到 observables。
  • 感谢您的评论。什么是从 http.post 请求中继续返回 observable 的最佳方法,同时仅在从 Storage 中检索到我的令牌变量后仍然执行它?

标签: javascript angular rxjs ionic3


【解决方案1】:

此答案的 2020 / 2021 版本如下,RequestOptions 已弃用,Observable.fromPromise 现在很简单 fromflatMap 现在是 mergeMap 并且您必须 pipe 到 mergeMap:

依赖/导入:

import { Observable, throwError, of, from } from 'rxjs';
import { map, catchError, mergeMap } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';

功能:

listProducts(){
return from(this.storage.get('token'))
  .pipe(mergeMap(token =>{
      const headers = new HttpHeaders().append('Content-Type', 'application/json').append('Authorization', 'Bearer ' + token);
      return this.http.get(`${url}`, { headers: headers })
  }
));
}

【讨论】:

    【解决方案2】:

    按照 caffinatedmonkey 的建议,我最终得到了这个工作函数:

        getPlanograms() {
    
        //API URL
        let requestURL = 'https://myapiurlhere';
    
        return Observable
            .fromPromise(this.storage.get('id_token'))
            .flatMap(token =>{
                let headers = new Headers({'Content-Type': 'application/json'});
                headers.append('Authorization', 'Bearer ' + token);
                let options = new RequestOptions({headers: headers});
                return this.http.get(requestURL, options)
                    .map(response => <Planogram[]>response.json())
                    .catch(this.handleError);
            }
        );
    }
    

    【讨论】:

      【解决方案3】:

      您可以通过更改使用.then()

      ionViewDidLoad () {
          this.merchandisingDataService.getPlanograms()
              .then(Planogram => this.planograms = Planogram);
      }
      

      或者,您可以让getPlanograms 返回Observable

      getPlanograms() {   
      
          // API URL
          let requestURL = 'https://myapiurlhere';
          let headers = new Headers({'Content-Type': 'application/json'});
      
          // this converts from promise to observable
          return Observable.fromPromise(this.storage.ready()
              .then(() => this.storage.get('id_token'))
              .then((val) => {
                  headers.append('Authorization', 'Bearer ' + this.authCredentials.token);
                  let options = new RequestOptions({headers: headers});
      
                  return this.http.post(requestURL, {}, options)
      
                      // map converts from observable to promise
                      // (returned by response.json())
                      .map(response => <Planogram[]>response.json());
              });
          }));
      }
      

      现在您可以像在问题中那样使用.subscribe() 消费。

      【讨论】:

      • 好主意,将 promise 转换为 observable :) +1 谢谢
      猜你喜欢
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-20
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      相关资源
      最近更新 更多