Angular中如何展示API返回的JSON响应值?
问题描述
我正在用Angular对接之前开发的Django Rest API,API有个端点返回当前登录用户数量。浏览器控制台能看到JSON响应,但页面上无法正确展示数值——模板里的users_online变量只显示[object Promise]。
我的模板代码:
<div *ngIf="authService.isLoggedIn()" class="fa fa-user">{{ users_online }}</div>
原app.service.ts代码:
import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {environment} from "../environments/environment"; import {firstValueFrom} from "rxjs"; export interface UsersOnlineCounterResponse { users_online: number; } const headers = { 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), } @Injectable({ providedIn: 'root' }) export class AppService { constructor(private http: HttpClient) { } async UsersOnlineCounter() { await firstValueFrom(this.http.get<UsersOnlineCounterResponse>(environment.backend + '/api/v1/users/online', {headers})).then(data => { return data.users_online; }); } }
原app.component.ts代码:
import { Component } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { AppService } from "./app.service"; import { AuthService } from "./auth/auth.service"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'example.com' users_online = this.appService.UsersOnlineCounter(); constructor(private titleService: Title, public authService: AuthService, public appService: AppService) { } ngOnInit() { this.titleService.setTitle(this.title); } }
解决方案
问题根源
UsersOnlineCounter是异步方法,直接赋值给users_online会得到Promise对象而非实际数值;- 服务中的异步方法没有正确返回结果;
- 组件中未在生命周期钩子中处理异步逻辑,而是直接初始化赋值。
方案1:修复异步方法并在组件中手动处理
1. 修正AppService方法
确保方法正确返回数值,同时动态获取token(避免token过期或更新后失效):
import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {environment} from "../environments/environment"; import {firstValueFrom} from "rxjs"; export interface UsersOnlineCounterResponse { users_online: number; } @Injectable({ providedIn: 'root' }) export class AppService { constructor(private http: HttpClient) { } async getUsersOnlineCounter(): Promise<number> { // 每次请求动态获取token const headers = { 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), }; const response = await firstValueFrom( this.http.get<UsersOnlineCounterResponse>(`${environment.backend}/api/v1/users/online`, {headers}) ); return response.users_online; } }
2. 修正AppComponent逻辑
初始化默认值,在ngOnInit中调用异步方法赋值:
import { Component } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { AppService } from "./app.service"; import { AuthService } from "./auth/auth.service"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'example.com'; users_online = 0; // 设置默认值 constructor( private titleService: Title, public authService: AuthService, public appService: AppService ) {} async ngOnInit() { this.titleService.setTitle(this.title); // 仅登录状态下获取数据 if (this.authService.isLoggedIn()) { this.users_online = await this.appService.getUsersOnlineCounter(); } } }
3. 可选:添加加载状态
模板中可以增加加载提示,优化用户体验:
<div *ngIf="authService.isLoggedIn()" class="fa fa-user"> {{ users_online === 0 ? '加载中...' : users_online }} </div>
方案2:使用Angular Async管道(更简洁)
如果不想手动处理异步逻辑,可以让服务返回Observable,通过Async管道自动订阅:
1. 修正AppService方法
import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {environment} from "../environments/environment"; import {Observable, map} from "rxjs"; export interface UsersOnlineCounterResponse { users_online: number; } @Injectable({ providedIn: 'root' }) export class AppService { constructor(private http: HttpClient) { } getUsersOnlineCounter(): Observable<number> { const headers = { 'Authorization': 'Bearer ' + localStorage.getItem('access_token'), }; return this.http.get<UsersOnlineCounterResponse>(`${environment.backend}/api/v1/users/online`, {headers}) .pipe(map(response => response.users_online)); } }
2. 修正AppComponent逻辑
import { Component } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { AppService } from "./app.service"; import { AuthService } from "./auth/auth.service"; import { Observable } from "rxjs"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'example.com'; users_online$: Observable<number>; // 用$后缀标识Observable constructor( private titleService: Title, public authService: AuthService, public appService: AppService ) {} ngOnInit() { this.titleService.setTitle(this.title); this.users_online$ = this.appService.getUsersOnlineCounter(); } }
3. 模板中使用Async管道
<div *ngIf="authService.isLoggedIn()" class="fa fa-user"> {{ users_online$ | async }} </div>
内容的提问来源于stack exchange,提问作者user18726875
相关产品推荐
相关产品推荐

