【问题标题】:http call not triggering in promise callback angular 2http调用未在promise回调角度2中触发
【发布时间】:2017-07-07 09:05:31
【问题描述】:

在我的 Angular 2 项目中,我进行了这个调用以获取一些数据:

this.http.getfromgraphql()
      .map((response: Response) => response.json())
      .subscribe(
        (data) => {
          console.log(data);
        });

这会触发下面显示的 getfromgraphql 函数,但在我进行调用之前,我必须检查访问令牌在 checkaccesstokenvalidity 中是否仍然有效,我在那里设置了一些变量并解析了函数。
控制台登录“然后”,但我的 http 帖子没有触发。
这是为什么呢?
另外,我确信有更好的方法可以做到这一点,但是对于我的生活我无法弄清楚,非常感谢更好的解决方案

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append( 'Content-Type', 'application/x-www-form-urlencoded' );
    let options = new RequestOptions({ headers: headers });
    // if(!this.access_token) {
    return new Promise((resolve, reject) => {
      this.http.post(this.URL + 'oauth/token', this.authentication, options)
        .subscribe(function(response) {
            this.authObj = response.json();
            this.expirationDate = new Date();
            this.expirationDate.setSeconds(this.expirationDate.getSeconds() + this.authObj.expires_in);
            console.log(this.authObj, this.expirationDate);
          },
          error => console.log("Error: ", error),
          function() {
            console.log('resolving');
            resolve();
          });

    });
    // }
  }
  getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({ headers: headers });

    this.checkAccessTokenValidity().then(function() {
      console.log('in then');
      //noinspection TypeScriptValidateTypes
      return this.http.post(this.URL + '/api/v1/graphql', this.query, options);
    });
  }

【问题讨论】:

  • getfromgraphql ()这个函数你是怎么使用的?
  • 我使用 this.http.getfromgraphql() 从某个组件调用 getfromgraphql 然后该函数从 checkaccesstokenvalidity() 获取一个新的访问令牌,之后它向端点 /api/v1/graphql 发布消息,但是不会触发。

标签: javascript angular promise observable angular2-http


【解决方案1】:

第 1 点:

不要在任何回调中使用function(){}。假设您使用的是 Typescript(或 ES6),您没有使用 lexical this。您的所有this 都将引用内部范围。你会得到很多未定义的。使用粗箭头符号()=>{}

第 2 点:

由于您已经在所有方法中使用Observables,因此请继续使用它们(反应式编程),除非必要,否则不要使用Promise

在您的getfromgraphql() 方法中,只需使用flatMap()。与promise中的.then()相同。

此外,在解决错误时,如果需要,只需执行.catch()。 Observables 会将错误传播给最高调用者。

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let options = new RequestOptions({headers: headers});
    return this.http.post(this.URL + 'oauth/token', this.authentication, options)
        .map(response => {
            this.authObj = response.json();
            this.expirationDate = new Date();
            this.expirationDate.setSeconds(this.expirationDate.getSeconds() + this.authObj.expires_in);
            console.log(this.authObj, this.expirationDate);
        })
        .catch(error=>{
            console.log(error);
            return Observable.empty();
        })
}

getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({headers: headers});

    return this.checkAccessTokenValidity().flatMap(()=>{
        console.log('in then');
        //noinspection TypeScriptValidateTypes
        return this.http.post(this.URL + '/api/v1/graphql', this.query, options);
    })
}

【讨论】:

  • 这给了我错误:“void”类型上不存在属性“subscribe”。在调用 this.http.getfromgraphql() .subscribe(response=> { console.log(response); });
  • @dennismuys 抱歉,您需要返回 observables。查看编辑
【解决方案2】:

我不明白你为什么要这样做 this.http.getfromgraphql() 但为了其他 反应式的代码是这样的:

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append( 'Content-Type', 'application/x-www-form-urlencoded' );
    let options = new RequestOptions({ headers: headers });
    return this.http
               .post(this.URL + 'oauth/token', this.authentication, options)
               .map(response => {
                   this.authObj = response.json();
                   this.expirationDate
                      .setSeconds((new Date())
                      .getSeconds() + this.authObj.expires_in);
               });
      }

getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({ headers: headers });

    this.checkAccessTokenValidity()
        .switchMap(token =>  this.http
               .post(this.URL + '/api/v1/graphql', this.query, options)   
 }

而你调用这个方法的方式是

someService.getfromgraphql()
           .subscribe(response=> {
// ....
});

【讨论】:

    【解决方案3】:

    尝试用这个替换你的帖子:

    return this.http.post(this.URL + '/api/v1/graphql', this.query, options).subscribe(() => {});
    

    看看它现在是否有效。

    【讨论】:

    • 法哈没有区别
    • 嗯。你能提供plunker吗?
    【解决方案4】:

    使用这个

    return this.http.post(this.heroesUrl, { name }, options)
           .toPromise()
    

    或在您的订阅中添加 resolve()

     .subscribe(function(response) {
            this.authObj = response.json();
            this.expirationDate = new Date();
            this.expirationDate.setSeconds(this.expirationDate.getSeconds() + 
            this.authObj.expires_in);
            console.log(this.authObj, this.expirationDate);
            resolve();
          },
    

    您可以在错误正文中使用reject(),而不是解决错误

    关注 plunker 会帮助你 https://embed.plnkr.co/?show=preview 检查 app/toh 文件夹中的 hero.service.promise.ts

    【讨论】:

    • 那个plunker好像是空的
    猜你喜欢
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    相关资源
    最近更新 更多