angular - 无法将从 http Get 返回的数据分配给具有相同结构的打字稿对象
问题描述
我正在从组件调用 http Get 服务方法,目的是将响应映射回组件内的 Person 对象,以便在前端显示。
我的组件:
export class DisplayPersonComponent implements OnInit {
personId: number;
person: Person;
constructor(private route: ActivatedRoute, private service : PersonService) { }
ngOnInit() {
this.route.params.subscribe(params => {
this.personId = params['person-id']});
this.getPerson(this.personId);
}
getPerson(id: number)
{
this.service.getPerson(id).subscribe((data: Person) => { console.log(data);
this.person = data
});
}
}
我的服务方法:
getPerson(personId : number): Observable<Person> {
let urlParams = new HttpParams().set("personId", personId.toString());
return this.http.get<Person>(this.apiUrl, { params: urlParams})
.pipe(map((data: Person ) => { return data }),
catchError(error => { return throwError(' Something went wrong! ');
})
);
}
}
我可以在组件返回时检查组件中的数据对象,它看起来像 json 即 { PersonID: 1, Name: 'Name'} 等 但是 this.Person 始终未定义,并且没有输出/错误来解释原因。还值得一提的是,我对 POST 方法使用了相同的对象,它工作正常,并且可以完美地从客户端映射到服务器,而无需任何指定的映射。
解决方案
变量this.personId
是异步分配的。所以在getPerson()
被调用的时候,它仍然是未定义的。
您可以使用 RxJS 高阶映射运算符代替嵌套订阅,例如switchMap
从一个 observable 映射到另一个。
ngOnInit() {
this.route.params.pipe(
switchMap(params => this.service.getPerson(params['person-id']))
).subscribe((data: Person) => {
console.log(data);
this.person = data;
})
}
选项2:async
管道
如果您不在this.person
控制器中使用,您可以跳过那里的订阅并async
在模板中使用管道
控制器
import { Observable } from 'rxjs';
export class DisplayPersonComponent implements OnInit {
person$: Observable<Person>; // <-- type `Observable`
constructor(private route: ActivatedRoute, private service : PersonService) { }
ngOnInit() {
this.person$ = this.route.params.pipe(
switchMap(params => this.service.getPerson(params['person-id']))
);
}
}
模板
<ng-container *ngIf="(person$ | async) as person">
{{ person }}
<some-comp [person]="person">...</some-comp>
</ng-container>
更新:Cannot read property
抛出错误是因为person
变量在订阅中被赋值之前是未定义的。使用第二个选项async
应该可以缓解这个问题。在任何情况下,您都可以使用安全导航运算符?.
来检查变量是否已定义,然后再尝试访问它的属性。
<div>
{{ person?.personId }}
{{ person?.someProp }}
{{ person?.someOtherProp }}
</div>
您可以在此处了解有关异步数据的更多信息。
推荐阅读
- amazon-web-services - 使用来自 AWS Lambda 的 Java 开发工具包将参数传递给 AWS Glue
- ssh - 如何在子域上设置 Mercurial 服务器?
- node.js - 如何分配承诺然后响应外部变量?
- javascript - NullInjectorError:没有 MatBottomSheetRef 的提供者
- javascript - 按字符串数组过滤javascript数组
- java - 使用 Android-Camera2 API 访问 USB 摄像头
- python - 如何从 numpy 数组创建 .fits 文件
- css - 如何在聊天室中将我的聊天条目与右侧对齐?
- php - 在 WooCommerce 快速订单预览中显示自定义字段
- flutter - 在 null 上调用了 getter 'classification'