【问题标题】:How can I get parts of JSON response and convert to an array of some interface?如何获取部分 JSON 响应并转换为某个接口的数组?
【发布时间】:2020-10-19 06:50:43
【问题描述】:

我需要获取我的应用程序的服务对后端执行的 GET 请求的 JSON 响应,获取其中的某些部分并将其放在我创建的接口数组中,以便我可以开始使用它。

这就是 JSON 的样子:

[{
        "id": 1,
        "name": "Lar das meninas",
        "latitude": -23.6695527,
        "longitude": -46.603418,
        "about": "Sobre o orfanato",
        "instructions": "Venha visitas",
        "opening_hours": "Das 8h até 18h",
        "open_on_weekends": false,
        "directory": {
            "directoryName": "/PROD/FILE",
            "server": {
                "serverName": "XYZ34"
            }
        }
    },
    {
        "id": 2,
        "name": "Petito Orfanato",
        "latitude": -23.6740118,
        "longitude": -46.6066612,
        "about": "Sobre o orfanato",
        "instructions": "Venha visitas",
        "opening_hours": "Das 8h até 18h",
        "open_on_weekends": false,
        "directory": {
            "directoryName": "/PROD/FILE",
            "server": {
                "serverName": "XYZ34"
            }
        }
    }
]

我只需要这些中的名称、纬度、经度、目录名和服务器名,所以我尝试创建这个界面来塑造响应:

export interface Orphanage {
  name: string,
  latitude: number,
  longitude: number
}

如您所见,由于嵌套,我什至没有尝试获取 directoryName 和 serverName。
我认为打字稿会匹配名称并仅获取界面中的内容,因此我进行了这样的调用并尝试 console.log 但它记录了整个响应。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Orphanage } from './orphanage';
import { tap } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class OrphanageService {

  constructor(private http: HttpClient) { }

  getOrphanages() {
    return this.http.get<Orphanage[]>('http://localhost:3333/orphanages').pipe(
      tap((res: Orphanage[]) => console.log(res))
    );
  }
}

我也尝试从组件调用服务,订阅 Observable,将其结果分配给组件的数组属性并 console.log 它,但得到相同的结果:

import { Component, OnInit } from '@angular/core';

import { Orphanage } from '../orphanage';
import { OrphanageService } from '../orphanage.service';

@Component({
  selector: 'app-orphanages-main',
  templateUrl: './orphanages-main.component.html',
  styleUrls: ['./orphanages-main.component.scss']
})
export class OrphanagesMainComponent implements OnInit {

  orphanages: Orphanage[];

  constructor(private orphanageService: OrphanageService) { }
 
  ngOnInit(): void {
    this.orphanageService.getOrphanages()
    .subscribe((orphanages: Orphanage[]) => {
      this.orphanages = orphanages;
      console.log(this.orphanages);
    });
  }
}

我需要做些什么来实现这一点,对于嵌套的 directoryName 和 serverName 我需要做些什么不同的事情?

谢谢!

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    您可以使用 RxJS 的 map 运算符来转换发出的数据,并使用 Array#map 方法根据现有数组的属性创建一个新数组。试试下面的

    界面

    export interface Orphanage {
      name: string;
      latitude: number;
      longitude: number;
      directoryName: string;
      serverName: string
    }
    

    服务

    export class OrphanageService {
      constructor(private http: HttpClient) { }
    
      getOrphanages() {
        return this.http.get<Orphanage[]>('http://localhost:3333/orphanages').pipe(
          map(orphanages =>
            orphanages.map(orphanage => {
              return <Orphanage>{
                name: orphanage['name'],
                latitude: orphanage['latitude'],
                longitude: orphanage['longitude'],
                directoryName: orphanage['directory']['directoryName'],
                serverName: orphanage['directory']['server']['serverName']
              }
            })
          ),
          tap((res: Orphanage[]) => console.log(res))
        );
      }
    }
    

    组件

    export class OrphanagesMainComponent implements OnInit {
      orphanages: Orphanage[];
    
      constructor(private orphanageService: OrphanageService) { }
     
      ngOnInit(): void {
        this.orphanageService.getOrphanages().subscribe({
          next: (orphanages: Orphanage[]) => {
            this.orphanages = orphanages;
            console.log(this.orphanages);
          },
          error: (error) => {
            // good practice to handle HTTP errors
          }
        });
      }
    }
    

    注意:将带有nexterror 回调的对象传递给订阅的原因是不推荐将回调直接传递给它。

    【讨论】:

      【解决方案2】:

      您可以使用 js map 方法从 json 创建 Orphanage 数组。 然后使用rxjs map 运算符将您在 Observeable 的流中接收到的每条数据映射为 Orphanage 数组:

      export interface Orphanage {
        name: string;
        latitude: number;
        longitude: number;
        directoryName: string;
        serverName: string;
      }
      
       getOrphanages(): Observable<Orphanage[]> {
          return this.http.get<any[]>('http://localhost:3333/orphanages').pipe(
            map(this.transformJsonToOrphanages)
          );
        }
      
      
       transformJsonToOrphanages(json): Orphanage[] {
         return json.map((jsonObj): Orphanage[] => {
            return {
               name: jsonObj.name,
               latitude: jsonObj.latitude,
               longitude: jsonObj.longitude,
               directoryName: jsonObj.directory.directoryName,
               serverName: jsonObj.directory.server.serverName
            }
          })
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-08
        • 2019-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-15
        • 2019-05-09
        • 2016-07-18
        相关资源
        最近更新 更多