Как мне отобразить объект JSON с вложенными массивами в модель typescript?

#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> . Молодец!