Angular 无法将 http 返回结果赋值给变量
Angular fails to assign http returned result to the variable
我正在尝试使用 ionic2 + angular2 制作一个应用程序,但我无法从服务器 api.
获取帐户验证结果(0:失败 1:success)
这是结果代码class
export class ResultCode{
result: number;
}
这是服务代码
@Injectable()
export class LoginService{
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http:Http){ }
authenticate(url:string,email:string, password:string): Promise<ResultCode>{
return this.http
.get(url)
.toPromise()
.then(res => res.json() as ResultCode)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.result || { };
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
这是登录页面代码
export class LoginPage {
resultCode:ResultCode;
private loginForm : FormGroup;
constructor(
public navCtrl: NavController,
private loginService:LoginService,
private formBuilder: FormBuilder) {
this.loginForm = this.formBuilder.group({
email: ['',[Validators.required,Validators.email]],
password: ['',[Validators.required,Validators.minLength(6)]]
});
}
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
}
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> this.resultCode = result);
}
}
然后我从控制台得到结果 == undefined。
我可以得到结果
result == 0
from console, if i print it inside the .then()
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> console.log("result == " + result.result));
}
我想知道 console.log 是否在 authenticate() 函数完成之前执行?谢谢你的帮助。
让我们仔细看看我们的代码:
login() {
//...
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
//...
}
控制台打印 result == undefined
的原因是因为在 login() 中您正在使用 authenticate()
进行异步调用。 虽然这是运行ning,但程序其余部分的执行会继续到console.log()
。因为 console.log() 执行速度比使用 authenticate() 发出网络请求快得多,所以它打印未定义,尽管后来 this.resultCode
中的值实际上是 0。
为了稍后在您的程序中处理响应,您必须等到它到达。因此,在 网络请求完成后 您想做的任何事情都需要在 authenticate()
函数的 .then()
部分进行编码,如下所示:
authenticate (url,email,password){
this.loginService.authenticate(url,email,password)
.then((result) => {
// NOW WE ARE ALWAYS SURE THE RESPONSE HAS ARRIVED
this.resultCode = result
});
}
现在,由于您有调用异步 authenticate() 的同步函数 login(),您可能想做一些事情,但 仅在 login() 及其调用的任何内容之后已完成。
最好的方法是使用 Promises。这就是我将如何更改您的代码以支持它:
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
return new Promise((resolve, reject) => { // notice we now return a Promise here too
this.authenticate(url,email,password)
.then(result){
this.resultCode = result;
resolve (result);
}
};
}
authenticate(url,email,password){
return new Promise((resolve, reject) => { // notice we now return a Promise
this.loginService.authenticate(url,email,password)
.then((result) => { resolve(result)); } // notice the change here, resolving the value outwards to the caller
};
}
现在,在登录页面代码的任何其他地方,如果您希望 运行 您确定在完全登录后执行的代码,您可以这样做:
login().then(){
// NOW WE ARE SURE LOGIN HAS COMPLETED
}
我正在尝试使用 ionic2 + angular2 制作一个应用程序,但我无法从服务器 api.
获取帐户验证结果(0:失败 1:success)这是结果代码class
export class ResultCode{
result: number;
}
这是服务代码
@Injectable()
export class LoginService{
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http:Http){ }
authenticate(url:string,email:string, password:string): Promise<ResultCode>{
return this.http
.get(url)
.toPromise()
.then(res => res.json() as ResultCode)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.result || { };
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
这是登录页面代码
export class LoginPage {
resultCode:ResultCode;
private loginForm : FormGroup;
constructor(
public navCtrl: NavController,
private loginService:LoginService,
private formBuilder: FormBuilder) {
this.loginForm = this.formBuilder.group({
email: ['',[Validators.required,Validators.email]],
password: ['',[Validators.required,Validators.minLength(6)]]
});
}
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
}
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> this.resultCode = result);
}
}
然后我从控制台得到结果 == undefined。
我可以得到结果
result == 0 from console, if i print it inside the .then()
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> console.log("result == " + result.result));
}
我想知道 console.log 是否在 authenticate() 函数完成之前执行?谢谢你的帮助。
让我们仔细看看我们的代码:
login() {
//...
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
//...
}
控制台打印 result == undefined
的原因是因为在 login() 中您正在使用 authenticate()
进行异步调用。 虽然这是运行ning,但程序其余部分的执行会继续到console.log()
。因为 console.log() 执行速度比使用 authenticate() 发出网络请求快得多,所以它打印未定义,尽管后来 this.resultCode
中的值实际上是 0。
为了稍后在您的程序中处理响应,您必须等到它到达。因此,在 网络请求完成后 您想做的任何事情都需要在 authenticate()
函数的 .then()
部分进行编码,如下所示:
authenticate (url,email,password){
this.loginService.authenticate(url,email,password)
.then((result) => {
// NOW WE ARE ALWAYS SURE THE RESPONSE HAS ARRIVED
this.resultCode = result
});
}
现在,由于您有调用异步 authenticate() 的同步函数 login(),您可能想做一些事情,但 仅在 login() 及其调用的任何内容之后已完成。
最好的方法是使用 Promises。这就是我将如何更改您的代码以支持它:
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
return new Promise((resolve, reject) => { // notice we now return a Promise here too
this.authenticate(url,email,password)
.then(result){
this.resultCode = result;
resolve (result);
}
};
}
authenticate(url,email,password){
return new Promise((resolve, reject) => { // notice we now return a Promise
this.loginService.authenticate(url,email,password)
.then((result) => { resolve(result)); } // notice the change here, resolving the value outwards to the caller
};
}
现在,在登录页面代码的任何其他地方,如果您希望 运行 您确定在完全登录后执行的代码,您可以这样做:
login().then(){
// NOW WE ARE SURE LOGIN HAS COMPLETED
}