#json #angular #typescript #rxjs #angular7
#json #angular #typescript #rxjs #angular7
Вопрос:
Предположим, у меня есть api, который возвращает следующую структуру JSON:
{
"Response": {
"status": {
"code": "SUCCESS",
"message": "owner found",
"count": "1"
},
"owners": [
{
"ownerId": "12345",
"name": "Example Person",
"cars": [
{
"make": "Toyota"
"year": "2004"
"model": "Camry"
}
]
}
]
}
}
Я хочу сопоставить эту структуру json с этими моделями typescript:
export class ApiResponse{
constructor(
public status: Status,
public owners: Owner[]
) {}
}
export class Status {
constructor(
public code: string,
public message: string,
public count: number
) {}
}
export class Owner{
constructor(
public ownerId: number,
public name: string,
public cars: Car[]
) {}
}
export class Car{
constructor(
public make: string;
public year: string;
public model: string;
)
}
Исходя из моего понимания angular 7, вы можете использовать pipe и map из rxjs для достижения этой цели:
this.http.get(url).pipe(
map((data: any[]) => data.map((item: any) => new ApiResponse(
new Status(
item.status.code,
item.status.message,
item.status.count),
...
Используя это, я могу сопоставить объект JSON, но я не уверен, как подойти к сопоставлению массивов и вложенных массивов.
Как мне следует подходить к сопоставлению JSON с вложенными массивами?
Комментарии:
1. Если определения вашей модели на самом деле не что иное, как списки свойств, они функционально эквивалентны интерфейсам. Таким образом, нет необходимости создавать экземпляры новых объектов, потому что ничего не получается — TS обеспечивает проверку типов как для интерфейсов, так и для классов. Просто верните
Observable
компоненту для рендеринга.
Ответ №1:
Если ваши классы не будут реализовывать какие-либо новые функциональные возможности, вы должны использовать интерфейсы только для обеспечения строгих типов, в противном случае это просто шаблон. Когда вы начали, вы можете получить свои 4 интерфейса таким образом и воспользоваться проверкой безопасности Typescript:
export interface ApiResponse{
status: Status,
owners: Owner[]
}
export interface Status {
code: string,
message: string,
count: number
}
export interface Owner{
ownerId: number,
name: string,
cars: Car[]
}
export interface Car{
make: string;
year: string;
model: string;
}
Ваш метод, который вызывает этот API, может быть написан следующим образом:
getStatusAndOwners(url): Observable<ApiResponse> {
return this.http.get(url);
}
Когда вы будете использовать данные (скорее всего, в блоке подписки), вы выиграете от «IntelliSense» и строгой типизации.
Удачи!
Комментарии:
1. Спасибо за ответ, это работает по мере необходимости. Следует отметить, что мне нужно было привести функцию get в соответствие с возвращаемым значением:
this.http.get<ApiResponse>(url);
2. Верно, потому что мы ожидаем
Observable<ApiResponse>
. Молодец!