Вы можете преобразовать ответ в модель следующим образом
getAllObjects(): Observable<MyObject[]> {
return this.http.get(this.url).pipe(
map((data: any[]) => data.map((item: any) => {
const model = new MyObject();
Object.assign(model, item);
return model;
}))
);
}
Или вы можете использовать универсальный класс преобразователя, который может принимать любой тип, извлекать предопределенные метаданные и выполнять преобразование данных.
export class ModelMapper<T> {
_propertyMapping: any;
_target: any;
constructor(type: { new(): T ;}){
this._target = new type();
this._propertyMapping = this._target.constructor._propertyMap;
}
map(source){
Object.keys(this._target).forEach((key) => {
const mappedKey = this._propertyMapping[key]
if(mappedKey){
this._target[key] = source[mappedKey];
}
else {
this._target[key] = source[key];
}
});
Object.keys(source).forEach((key)=>{
const targetKeys = Object.keys(this._target);
if(targetKeys.indexOf(key) === -1){
this._target[key] = source[key];
}
});
return this._target;
}
}
Теперь импортируйте этот класс в service.ts и используйте его для преобразования ответа json.
import { ModelMapper } from './modelMapper';
public get<T>(url: string, itemType: any): Observable<T> {
if (!url) {
return;
}
return this.http.get<T>(url)
.pipe(
map(data => data.map((item: any) => {
return new ModelMapper(itemType).map(item);
}
))
);
}
}
Если вы хотите выполнить переименование поля данных бэкенда, вы можете создать декоратор PropertyMap, как показано ниже
export function propertyMap(sourceProperty : string) {
return function (target: any, propertyKey : string) {
if(!target.constructor._propertyMap) {
target.constructor._propertyMap = {};
}
target.constructor._propertyMap[propertyKey] = sourceProperty;
}
}
Затем вы используете его в классе вашей модели
@propertyMap('namealias')
public name: string;