将角度 http 响应转换为类

kro*_*761 6 observable angular angular-httpclient

我正在尝试将响应对象从我的 angular 项目中的 HTTP Post 请求转换为Person我定义的类。我在 HTTP 服务中定义了一个通用的 post 方法,并在我的个人服务中调用它,将通用替换为Person. 所以,我想,既然我已经做了 HTTPresponse应该是一个Person,但它不是 - 它只是一个Object. 我需要它是 aPerson因为我的 Person 类上有一些我需要访问的自定义逻辑。我可以在我的个人服务中编写一个辅助方法,但我觉得这应该可行 - 特别是因为 VS Code 智能感知说response我的组件中的 是Person当我将鼠标悬停在它上面时。

这是我的代码:

http.service.ts

@Injectable()
export class HttpService {
    baseUrl = 'https://baseurl.com';

    constructor(private http: HttpClient) { }

    post<T>(endpointUrl: string, body: any): Observable<T> {
        const fullUrl = this.baseUrl + endpointUrl;
        return this.http
            .post<T>(fullUrl, body)
            .pipe(
                map(response => response as T)
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

person.service.ts

@Injectable()
export class PersonService {

    constructor(private httpService: HttpService) { }

    newPerson(body: Person): Observable<Person> {
        return this.httpService.post<Person>('/people', JSON.stringify(body));
    }
}
Run Code Online (Sandbox Code Playgroud)

person.component.ts

@Component({
    selector: 'app-person',
    templateUrl: './person.component.html',
    styleUrls: ['./person.component.css'],
})
export class PersonComponent {
        person: Person = new Person();

        onSubmit(id: number) {
        if (id == 0) {
            console.log(this.person);                              // Person {id: 0, ...
            console.log(this.person.constructor.name);             // Person
            let body = this.person.fromFormGroup(this.formGroup);

            this.personService.newPerson(body)
                .subscribe(response => {                           // VS Code intellisense says this: (parameter) response : Person
                    this.person = response as Person;
                    console.log(this.person);                      // {id: 72, ...
                    console.log(this.person.constructor.name);     // Object

                    // Trying a different way
                    this.person = <Person>response;
                    console.log(this.person);                      // {id: 72, ...
                    console.log(this.person.constructor.name);     // Object
                })

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Rea*_*lar 15

newPerson(body: Person): Observable<Person> {
  return this.httpService.post<Person>('/people', JSON.stringify(body));
}
Run Code Online (Sandbox Code Playgroud)

HttpClient.post()方法不能返回 type Person,因为 JSON 响应只是转换为类型。默认类型只是Object,但您需要Person为每个响应创建一个新实例。如果类型是一个接口,那么就没有问题。

您可以创建一个新实例,Person然后将值分配给该实例。

newPerson(body: Person): Observable<Person> {
  return this.httpService.post('/people', JSON.stringify(body)).pipe
    map(value => Object.assign(new Person(), value)
  );
}
Run Code Online (Sandbox Code Playgroud)


use*_*584 5

来自 http 服务的响应将是一个 json 对象,该对象被反序列化为 javascript 对象。您的 person 服务无法将 api 响应中收到的 JavaScript 对象转换为开箱即用的 person 对象。请记住,打字稿代码被转换为 JavaScript 代码。要将 javascript 对象转换为 Person 类对象,您必须手动实例化您的类对象,并通过将响应投影到 person 对象来填充 api 响应中的属性。您可以执行以下操作[注意地图操作员用于预测对人的响应]-

person.service.ts

@Injectable()
export class PersonService {

  constructor(private httpService: HttpService) {}

  newPerson(body: Person): Observable<Person> {
    return this.httpService.post<Person>('/.people', JSON.stringify(body))
      .pipe(
        map(response => {

          const person = new Person();
          //fill the person props from response
          return person;
        }),
      );
  }
}
Run Code Online (Sandbox Code Playgroud)