Приведите угловой http ответ в класс - PullRequest
0 голосов
/ 01 июня 2019

Я пытаюсь преобразовать объект ответа из HTTP-запроса в моем угловом проекте в определенный класс Person. Я определил универсальный метод post в HTTP-сервисе и вызываю его в моем сервисе person с универсальным значением, замененным на Person. Итак, я думаю, поскольку я сделал, что HTTP response должен быть Person, но это не так - это просто Object. Мне нужно, чтобы он был Person, потому что в моем классе Person есть некоторая пользовательская логика, к которой мне нужно получить доступ. Я мог бы написать вспомогательный метод в моем личном сервисе, но я чувствую, что это должно сработать - тем более, что VS Code intellisense говорит, что 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)
            );
    }
}

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));
    }
}

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
                })

        }
    }

}

Ответы [ 2 ]

2 голосов
/ 02 июня 2019
    newPerson(body: Person): Observable<Person> {
        return this.httpService.post<Person>('/people', JSON.stringify(body));
    }

Метод HttpClient.post() не может возвращать тип Person, поскольку ответы JSON просто приводятся к типам.Тип по умолчанию - просто Object, но вам нужно создать новый экземпляр Person для каждого ответа.Если бы тип был interface , то проблем не было бы.

Вы можете создать новый экземпляр Person и затем присвоить значения этому экземпляру.

    newPerson(body: Person): Observable<Person> {
        return this.httpService.post('/people', JSON.stringify(body)).pipe
           map(value => Object.assign(new Person(), value)
        );
    }
0 голосов
/ 01 июня 2019

Ответом от службы http будет объект json, который десериализуется в объект javascript. Ваш персональный сервис не может конвертировать объект JavaScript, полученный в ответе API, на персональный объект из коробки. Помните, что машинописный код переносится в код JavaScript. Чтобы преобразовать объект javascript в объект класса Person, вам придется вручную создать экземпляр объекта класса и заполнить свойства из ответа API, проецируя ответ на объект person. Вы можете сделать следующее [обратите внимание, оператор карты, используемый для проецирования ответа человеку] -

    //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;
     })
   );
    }
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...