Angular订阅Observable后报Converting circular structure to JSON错误求助
错误原因
- 你在
TicketlistComponent的getTickets方法中,将Observable.subscribe()的返回值赋值给了getTickets$:this.getTickets$ = this.connService.getTicketList().subscribe();
这里subscribe()方法返回的是Subscription订阅对象,不是接口返回的业务数据,也不是原始的Observable对象。 - 模板中你调用了
{{ getTickets$ | json }},Angular的JsonPipe底层会调用JSON.stringify()转换传入的值,而Subscription对象内部存在循环引用结构,直接序列化就会触发你遇到的循环结构转换报错。
解决方案
方案1:使用AsyncPipe自动订阅(推荐)
AsyncPipe会自动管理Observable的订阅、销毁,不需要你手动调用subscribe:
- 修改TicketlistComponent代码:
export class TicketlistComponent implements OnInit { constructor(private connService : ConnectionsService) { } // 直接保存Observable,不要调用subscribe getTickets$ : Observable<ITicketList[]>; ngOnInit(): void { console.log('ngOnInit') this.getTickets$ = this.connService.getTicketList(); } }
- 打开模板中被注释的AsyncPipe相关代码,去掉直接对getTickets$用json pipe的写法:
<p>ticketlist works!</p> <div *ngIf="getTickets$ | async as getTickets; else loading"> {{ getTickets | json }} </div> <ng-template #loading> loading... </ng-template>
这里async as会等Observable返回结果后,把实际的业务数据赋值给getTickets变量,再用JsonPipe序列化业务数据就不会有循环引用问题。
方案2:手动订阅赋值给业务变量
如果你需要在订阅回调中做额外的业务处理,可以手动订阅,把返回的数据赋值给普通变量:
- 修改TicketlistComponent代码:
export class TicketlistComponent implements OnInit { constructor(private connService : ConnectionsService) { } // 声明普通变量保存业务数据 ticketList: ITicketList[] = []; loading = true; ngOnInit(): void { console.log('ngOnInit') this.connService.getTicketList().subscribe(res => { this.ticketList = res; this.loading = false; }); } }
- 模板对应修改为:
<p>ticketlist works!</p> <div *ngIf="!loading; else loading"> {{ ticketList | json }} </div> <ng-template #loading> loading... </ng-template>
内容的提问来源于stack exchange,提问作者John Lee Hedge
相关产品推荐
相关产品推荐

