Angular 打字稿异步 HTTPClient 调用
Posted
技术标签:
【中文标题】Angular 打字稿异步 HTTPClient 调用【英文标题】:Angular typescript Async HTTPClient call 【发布时间】:2021-11-12 07:48:51 【问题描述】:我有问题。在我的角度项目中,我正在尝试进行 Http POST 调用,以登录我的网站。我向呼叫提供用户名和密码。如果 API 端点返回 null,则登录失败,如果端点返回 Account 对象,则登录成功。进行 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()
函数总是返回null。我知道我必须使用某种异步/等待,但我似乎无法弄清楚如何在我的情况下使用它。这是我尝试过的。在 AccountService 中:
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;
有人可以告诉我如何解决和优化(如果可能的话)吗?
【问题讨论】:
你能不能把console.log(data)
上面的if(data != null)
打印出来,也许你需要先把结果映射出来
【参考方案1】:
问题是login()函数总是返回null
是的,从login
方法返回数据的方式存在问题。您使用 subscribe
异步执行但不返回任何值。你应该使用类似map
的东西。请参阅此帖子以了解更多详细信息:Return a Observable from a Subscription with RxJS
因此,如果您尝试这样的事情(未测试),您的 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 打字稿异步 HTTPClient 调用的主要内容,如果未能解决你的问题,请参考以下文章