无法将http Get返回的数据分配给具有相同结构的打字稿对象 选项2:ngOnInit() { this.route.params.pipe( switchMap(params => this.service.getPerson(params['person-id'])) ).subscribe((data: Person) => { console.log(data); this.person = data; })

问题描述

我正在从组件中调用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,名称:“名称”}等 但是this.Person始终是未定义的,没有输出/错误可以解释原因。 值得一提的是,我对POST方法使用了相同的对象,并且工作正常,并且可以从客户端到服务器完美映射,而无需任何指定的映射。

解决方法

变量this.personId是异步分配的。因此,在调用getPerson()时,它仍未定义。

您可以使用{x {1}}之类的RxJS高阶映射运算符,而不是嵌套订阅,来从一个可观察对象映射到另一个。

switchMap

选项2:ngOnInit() { this.route.params.pipe( switchMap(params => this.service.getPerson(params['person-id'])) ).subscribe((data: Person) => { console.log(data); this.person = data; }) } 管道

如果您未在控制器中使用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来检查变量是否已定义,然后再尝试访问其属性。

?.

您可以了解有关异步数据here的更多信息。

,

可观察对象是(x1 < x2) * 2 - 1,在您评估async时,尚未调用可观察对象完成时调用的内部订阅方法。

我不知道您在哪里使用person对象,但似乎您需要重新考虑一下逻辑。

幸运的是,angular具有异步管道,可以与* ngIf一起使用:

person

此管道接收一个可观察的对象,并将其“解析”为html模板中的person对象。它也仅在此请求完成后呈现其中的内容,因此您可以在内部自由使用对象的属性!

来源和更多信息: https://ultimatecourses.com/blog/angular-ngif-async-pipe

,

您的服务方法返回一个可观察值,而不是直接返回该人。 因此,如果您在可观察对象实际返回对象之前检查人员对象,则它将是未定义的。 这不是错误,而只是异步代码的工作方式。

在标记中,只需确保在呈现对象之前检查该对象是否未定义:

<div *ngIf="person">...</div>

您的POST方法起作用的原因是,您实际上可能没有对响应做任何事情。例如,如果要执行诸如在POST成功时显示敬酒通知之类的操作,则将应用相同的原理,则必须观察POST响应并对成功/错误进行操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...