У меня вопрос по Angular 5 httpClient.
Это модельный класс с методом foo (), который я хотел бы получить от сервера
export class MyClass implements Deserializable{
id: number;
title: string;
deserialize(input: any) {
Object.assign(this, input);
return this;
}
foo(): string {
// return "some string conversion" with this.title
}
}
Это моя служба запрашивает это:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { MyClass } from './MyClass';
@Injectable({
providedIn: 'root',
})
export class MyClassService {
constructor(private http: HttpClient) {
}
getMyStuff(): Observable<MyClass[]> {
// this is where I hope to convert the json to instances of MyClass
return this.http.get<MyClass[]>('api/stuff')
}
}
Когда я запрашиваю у службы экземпляры MyClass, я получаю данные, но не могу запустить {{ item.foo() }} в шаблоне. Кроме того, когда я console.info()typeof элемента, где он получен в службе, я не вижу экземпляров объекта MyClass.
Что я делаю неправильно? Я думал, что запись this.http.get<MyClass[]>('api/stuff') сделает преобразование.
Какие-нибудь намеки? Заранее спасибо!
Аналогичный вопрос к stackoverflow.com/questions/47499324/…
аналогичный вопрос здесь stackoverflow.com/questions/63964124/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


При этом TypeScript выполняет только «утверждение типа». Это означает, что вы сообщаете TypeScript, что ваш объект относится к типу MyClass, но на самом деле этот объект не является экземпляром MyClass во время выполнения. Чтобы вызывать функции, определенные в вашем объекте модели, вы должны определить конструкторы в своих классах модели следующим образом:
constructor(obj?: any) {
Object.assign(this, obj);
}
Затем в ваших сервисах добавьте сопоставление, подобное этому:
http.get<MyClass>('/my-class').pipe(
map(res => new MyClass(res))
Примечание: приведенный выше код выполнен в стиле RxJS 6, я не знаю, какую версию вы используете.
Благодаря вам я перечитал этот учебник, что не дочитал до конца. Сейчас я делаю в службе следующее: `return stuffObjects.map (stuff => new MyClass (). Deserialize (stuff));
Пожалуйста, мне лично нравится конструкторский способ, интерфейс Deserialize - еще один подходящий вариант
это будет работать, только если MyClass не имеет сложных членов (например, членов типа Date или других классов)
@ Jota.Toledo да, и это можно решить, определив сеттеры для этих свойств
спасибо очень полезно stackoverflow.com/questions/36014161/…
У меня это работает вот так
import { HttpClient } from '@angular/common/http';
...
this.httpClient.get<MyResponse>('http://......').toPromise()
.then((myResponse) => {
console.info('myResponse.myField: ' + JSON.stringify(tokenResponse));
})
.catch((error) => {
console.info('Promise rejected with ' + JSON.stringify(error));
});
...
interface MyResponse {
myField: string;
myOtherField: string;
}
Пожалуйста, добавьте пояснение к своему ответу, чтобы другие могли извлечь из него уроки.
Пожалуйста, прочтите вопрос еще раз, он касается вызова функций в бизнес-классе, гидратированном из бэкэнда, как интерфейс решает эту проблему?
@GuerricP этот вопрос касается десериализации ответа сервера в модель, и это именно то, что делает мой код.
Прочтите это, чтобы понять, как использовать Deserializable в вашей модели с данными из API. nehalist.io/working-with-models-in-angular