Angular2 Mapping nested json array to model

2019-03-11 06:40发布

问题:

I am not able to map the nested json array which is response from Web to my model array in Angular2. Suppose I have json array response as below:

[{
    "base_url": "http://mysearch.net:8080/",
    "date": "2016-11-09",
    "lname": "MY PROJ",
    "name": "HELLO",
    "description": "The Test Project",
    "id": 10886789,
    "creationDate": null,
    "version": "2.9",
    "metrics": [{
        "val": 11926.0,
        "frmt_val": "11,926",
        "key": "lines"
    },
    {
        "val": 7893.0,
        "frmt_val": "7,893",
        "key": "ncloc"
    }],
    "key": "FFDFGDGDG"
}]

I was trying to manually map the fields referring the link Angular 2 observable doesn't 'map' to model to my model and was able to display those in my HTML by iterating through ngFor.....but I want to also display ncloc and lines value also in the HTML but I am not sure how to map those values to my Model array like mentioned in the above link. Can you please help me with this?

Thanks.

EDIT

Mode class

export class DeiInstance { 
    base_url: string;
    date: string;
    lname : string;
    name : string;
    id : number;
    key:string;

    constructor(obj: DeiInstance) {
        this.sonar_url = obj['base_url'];
        this.lname = obj['lname'];
        this.name = obj['name'];
        this.id = obj['id'];
        this.key = obj['key'];
        this.date = obj['date'];
    } 

    // New static method. 
    static fromJSONArray(array: Array<DeiInstance>): DeiInstance[] {
        return array.map(obj => new DeiInstance(obj));
    } 
 } 

回答1:

You can simplify your model and your mapping a lot. You don't need to map your API response manually. JavaScript/TypeScript can do this for you.

First you need multiple interfaces.

export interface DeiInstance { 
    base_url: string;
    date: string;
    lname: string;
    name: string;
    description: string;
    id: number;
    creationDate: string; //probably date
    version: string
    metrics: Metric[];
    key: string;
 }

 export interface Metric {
      val: decimal;
      frmt_val: decimal;
      key: string;
 }

You can then use the as-"operator" of TypeScript to cast your API response to the DeiInstance Type.

 sealSearch(term: string): Observable<DeiInstance[]> {
      return this.http.get(this.sealUrl + term)
           .map(response => response.json() as DeiInstance[])
           .catch(this.handleError);
 }

If you use interfaces instead of classes you have also the advantage that you have less production code which will be sended to the client browser. The interface is only there for pre-compile-time or however you want to call it.

Hope my code works and it solves your problem.