Angular 打字稿异步 HTTPClient 调用
Angular typescript Async HTTPClient call
我有问题。在我的 angular 项目中,我正在尝试进行 Http POST 调用,以登录我的网站。我为通话提供了用户名和密码。如果 API 端点 returns 为空,则登录失败,如果端点 returns 一个帐户对象,则登录成功。进行 Http POST 调用的代码如下:
import { Injectable } from '@angular/core';
import {Account} from "../models/Account";
import {Observable} from "rxjs";
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {PostService} from "./post.service";
@Injectable({
providedIn: 'root'
})
export class AccountService {
public loggedInAccount: Account | null;
private httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
//Authorization: 'my-auth-token'
})
};
constructor(private httpClient: HttpClient) {
this.loggedInAccount = null;
}
public login(account: Account):Account | null {
this.restLogin(account).subscribe(
(data) => {
if (data != null) {
this.loggedInAccount = data;
}
return data;
},
(error) => {
alert('Error: Status ' + error.status + ' - ' + error.error);
});
return null;
}
private restLogin(account: Account): Observable<Account> {
let email = account.email;
let password = account.password;
return this.httpClient.post<Account>('http://localhost:8080/account/login', {email, password}, this.httpOptions);
}
}
问题是 login()
函数总是 returns 为空。我知道我必须使用某种 async/await,但我似乎无法弄清楚如何在我的案例中使用它。这是我试过的。在账户服务中:
public async login(account: Account):Promise<Account | null> {
let returnValue = null;
await this.restLogin(account).subscribe(
(data) => {
if (data != null) {
this.loggedInAccount = data;
}
returnValue = data;
},
(error) => {
alert('Error: Status ' + error.status + ' - ' + error.error);
});
return returnValue;
}
登录页面:
public onLoginClick(): void {
let email = (document.getElementById("txtEmail") as HTMLInputElement).value;
let password = (document.getElementById("txtPassword") as HTMLInputElement).value;
if (this.accountService.login(new Account(email, password)) != null) {
this.accountService.loggedInAccount!.posts = this.postService.getAccountPosts(this.accountService.loggedInAccount!.id);
this.route.navigate(['/']);
}
else {
(document.getElementById("txtMessage") as HTMLDivElement).innerHTML = "Incorrect email/password!"
}
}
但这让我在登录页面的这一行出现错误:
this.accountService.loggedInAccount!.posts = this.postService.getAccountPosts(this.accountService.loggedInAccount!.id);
说 this.accountService.loggedInAccount
为空,但这是不可能的,因为我在 de AccountService:
中设置了它
if (data != null) {
this.loggedInAccount = data;
}
return data;
有人能告诉我如何修复和优化(如果可能)这个问题吗?
The problem is that the login() function always returns null
是的,return 来自 login
方法的数据存在问题。您使用 subscribe
以异步方式执行但不 return 任何值。你应该使用像 map
. See this post with more details :
这样的东西
因此,如果您尝试这样的操作(未测试),您的 login
函数应该可以工作:
public login(account: Account): Observable<Account | null> {
return this.restLogin(account)
.pipe(
map(result => {
// TODO: do something with "result" ?
// If not, you can remove the "map" pipe and only keep "catchError"
return result;
}),
catchError(error => {
// TODO: handle error
return of(null);
})
);
}
然后你可以像这样调用你的 login
方法:
this.accountService.login(new Account(email, password)).subscribe(account => {
if (account !== null) {
// Login succeeded, redirect
} else {
// Login failed
}
})
我有问题。在我的 angular 项目中,我正在尝试进行 Http POST 调用,以登录我的网站。我为通话提供了用户名和密码。如果 API 端点 returns 为空,则登录失败,如果端点 returns 一个帐户对象,则登录成功。进行 Http POST 调用的代码如下:
import { Injectable } from '@angular/core';
import {Account} from "../models/Account";
import {Observable} from "rxjs";
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {PostService} from "./post.service";
@Injectable({
providedIn: 'root'
})
export class AccountService {
public loggedInAccount: Account | null;
private httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
//Authorization: 'my-auth-token'
})
};
constructor(private httpClient: HttpClient) {
this.loggedInAccount = null;
}
public login(account: Account):Account | null {
this.restLogin(account).subscribe(
(data) => {
if (data != null) {
this.loggedInAccount = data;
}
return data;
},
(error) => {
alert('Error: Status ' + error.status + ' - ' + error.error);
});
return null;
}
private restLogin(account: Account): Observable<Account> {
let email = account.email;
let password = account.password;
return this.httpClient.post<Account>('http://localhost:8080/account/login', {email, password}, this.httpOptions);
}
}
问题是 login()
函数总是 returns 为空。我知道我必须使用某种 async/await,但我似乎无法弄清楚如何在我的案例中使用它。这是我试过的。在账户服务中:
public async login(account: Account):Promise<Account | null> {
let returnValue = null;
await this.restLogin(account).subscribe(
(data) => {
if (data != null) {
this.loggedInAccount = data;
}
returnValue = data;
},
(error) => {
alert('Error: Status ' + error.status + ' - ' + error.error);
});
return returnValue;
}
登录页面:
public onLoginClick(): void {
let email = (document.getElementById("txtEmail") as HTMLInputElement).value;
let password = (document.getElementById("txtPassword") as HTMLInputElement).value;
if (this.accountService.login(new Account(email, password)) != null) {
this.accountService.loggedInAccount!.posts = this.postService.getAccountPosts(this.accountService.loggedInAccount!.id);
this.route.navigate(['/']);
}
else {
(document.getElementById("txtMessage") as HTMLDivElement).innerHTML = "Incorrect email/password!"
}
}
但这让我在登录页面的这一行出现错误:
this.accountService.loggedInAccount!.posts = this.postService.getAccountPosts(this.accountService.loggedInAccount!.id);
说 this.accountService.loggedInAccount
为空,但这是不可能的,因为我在 de AccountService:
if (data != null) {
this.loggedInAccount = data;
}
return data;
有人能告诉我如何修复和优化(如果可能)这个问题吗?
The problem is that the login() function always returns null
是的,return 来自 login
方法的数据存在问题。您使用 subscribe
以异步方式执行但不 return 任何值。你应该使用像 map
. See this post with more details :
因此,如果您尝试这样的操作(未测试),您的 login
函数应该可以工作:
public login(account: Account): Observable<Account | null> {
return this.restLogin(account)
.pipe(
map(result => {
// TODO: do something with "result" ?
// If not, you can remove the "map" pipe and only keep "catchError"
return result;
}),
catchError(error => {
// TODO: handle error
return of(null);
})
);
}
然后你可以像这样调用你的 login
方法:
this.accountService.login(new Account(email, password)).subscribe(account => {
if (account !== null) {
// Login succeeded, redirect
} else {
// Login failed
}
})