http 调用未在 promise 回调中触发 angular 2
http call not triggering in promise callback angular 2
在我的 angular 2 项目中,我进行此调用以获取一些数据:
this.http.getfromgraphql()
.map((response: Response) => response.json())
.subscribe(
(data) => {
console.log(data);
});
这会触发如下所示的 getfromgraphql 函数,但在我进行该调用之前,我必须在 checkaccesstokenvalidity 中检查访问令牌是否仍然有效,我在那里设置了一些变量并解析了该函数。
控制台记录 'in then' 但我的 http post 没有触发。
这是为什么?
另外,我确信有更好的方法来做到这一点,但对于我的生活我无法弄清楚,非常感谢更好的解决方案
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);
});
}
尝试用这个替换你的 post 电话:
return this.http.post(this.URL + '/api/v1/graphql', this.query, options).subscribe(() => {});
看看它现在是否有效。
我不明白你为什么要这样做 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=> {
// ....
});
第 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);
})
}
使用这个
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
在我的 angular 2 项目中,我进行此调用以获取一些数据:
this.http.getfromgraphql()
.map((response: Response) => response.json())
.subscribe(
(data) => {
console.log(data);
});
这会触发如下所示的 getfromgraphql 函数,但在我进行该调用之前,我必须在 checkaccesstokenvalidity 中检查访问令牌是否仍然有效,我在那里设置了一些变量并解析了该函数。
控制台记录 'in then' 但我的 http post 没有触发。
这是为什么?
另外,我确信有更好的方法来做到这一点,但对于我的生活我无法弄清楚,非常感谢更好的解决方案
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);
});
}
尝试用这个替换你的 post 电话:
return this.http.post(this.URL + '/api/v1/graphql', this.query, options).subscribe(() => {});
看看它现在是否有效。
我不明白你为什么要这样做 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=> {
// ....
});
第 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);
})
}
使用这个
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