简体   繁体   English

Angular 9 http 响应后的类型转换问题

[英]Angular 9 typecast issue after http response

I have a component which retrieves a student info from an api upon its initialization.我有一个组件,它在初始化时从 api 检索学生信息。 This is the onIniti code on my cmponent-version1这是我的cmponent-version1上的onIniti代码

ngOnInit(): void {
    if(!this.student) {
      this.studentsService.getStudentDetail(this.id).subscribe(
        (response: Student) => {
          this.student = response;
        },
        error => console.log(error)
      )
    }
  }

and here is the function inside my student-service-version1这是我的学生服务版本1中的function

getStudentDetail(id: number): Observable<Student> {
    return this.httpClient.get<Student>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
  }

Everything works fine.一切正常。 Now, just for didactic purpose (I'm new to javascript/typescript), I'd like to refactor my service in order to use a single get function which returns the list of students when called without parameter, and instead return a student detail info when called with a specific id.现在,仅出于教学目的(我是 javascript/typescript 的新手),我想重构我的服务,以便使用单个get function 在不带参数的情况下返回学生列表,而是返回学生详细信息使用特定 ID 调用时的信息。 This is the students-service-version2这是学生服务版本2

getStudents(id?: number): Observable<Student[]> {
    if(id)
      return this.httpClient.get<Student[]>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
    else
      return this.httpClient.get<Student[]>(this.studentsUrl, this.baseService.httpOptions);
  }

Given that the signature of my function states it returns a students array observable, in my component I need a sort of typecasting from Student[] to Student .鉴于我的 function 的签名声明它返回一个可观察的学生数组,在我的组件中,我需要一种从Student[]Student的类型转换。 This is how I do it: component-version2我就是这样做的: component-version2

ngOnInit(): void {
    if(!this.student) {
      this.studentsService.getStudents(this.id).subscribe(
        (response: Student[]) => {
          this.student = response[0] as Student;
        },
        error => console.log(error)
      )
    }
  }

This doesn't work so after the init, student var remains undefined.这不起作用,因此在 init 之后, student var 仍然未定义。 I do not understand why, everything seems correct to me (although this refactoring it's not a good idea. Again, I just want to understand the error behind) I'vs also try this.student = response.pop() as Student;我不明白为什么,对我来说一切似乎都是正确的(尽管这种重构不是一个好主意。同样,我只是想了解背后的错误)我也尝试this.student = response.pop() as Student; Same result, not working.同样的结果,不工作。

ngOnInit(): void {
if(!this.student) {
  this.studentsService.getStudents(this.id).subscribe(
    (response: Student[]) => {
      // Hope, this.student will have type as any, public student: any
      this.student = !this.id ? response[0] as Student : response as Student[];
    },
    error => console.log(error)
  )
}

} }

Always, try to return an array to avoid conflicts.始终,尝试返回一个数组以避免冲突。 In the above code, the ternary operator will do your work.在上面的代码中,三元运算符将完成您的工作。 As, if you have an id that means you are asking for particular student information otherwise you are asking for all student records.因为,如果您有一个 id,这意味着您正在询问特定的学生信息,否则您正在询问所有学生记录。

your service should be yelling at you right now because you're lying to the compiler... your return type isn't Observable<Student[]> its Observable<Student[] | Student>您的服务现在应该对您大喊大叫,因为您在对编译器撒谎……您的返回类型不是Observable<Student[]>它的Observable<Student[] | Student> Observable<Student[] | Student> ... i don't agree with the principal of one function for both single and list gets at all, but you could force it to be a list in the single case... Observable<Student[] | Student> ...我不同意一个 function 的负责人,无论是单身还是名单,但你可以强迫它成为单一情况下的名单......

return this.httpClient.get<Student>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions).pipe(
  map(student => [student])
);

no typecasting will convert something to an array if its not an array.如果它不是数组,则没有类型转换会将其转换为数组。 you need to explicitly make it an array if that's waht you want.如果您愿意,您需要明确地将其设为数组。

Overload the signature of your method as follows:重载方法的签名,如下所示:

class StudentService {
  get(id: number) | Observable<Student>;
  get(): Observable<Student[]>;
  get(id: number | undefined): Observable<Student[]> | Observable<Student> {
    if(id !== undefined)
      return this.httpClient.get<Student[]>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
    else
      return this.httpClient.get<Student>(this.studentsUrl, this.baseService.httpOptions);
  }
} 

Notice how the method has been renamed to make sense in either case, how the return type is correlated with the presence of the id parameter, and how the check has been modified to accommodate the possibility of 0 as a valid id.请注意如何重命名该方法以使其在任何一种情况下都有意义,返回类型如何与id参数的存在相关,以及如何修改检查以适应0作为有效 id 的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM