简体   繁体   中英

Typescript Mapping Values into Model Type

I have the following service:

import { Component } from '@angular/core';
import { ApiService } from './shared/api.service';
import {PowerPlant} from './shared/models/powerplant.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  powerPlants: PowerPlant[];

  constructor(private apiService: ApiService) {
  }

  allPowerPlants(onlyActive: boolean = false, page: number = 1): void {
    const path = `$/powerPlants?onlyActive${onlyActive}&page${page}`;
    this.apiService.get(path).map() // TODO: parse and set the JSON to my model
  }
}

In the get method of the apiService, this is what I do:

get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> {
    return this.http.get(`${environment.api_url}${path}`, { headers: this.setHeaders(), search: params })
      .catch(this.formatErrors)
      .map((res: Response) => res.json());
  }

So I would like to parse this Json array, if there are any errors in any one of the array element, I would like to ignore it and populate the powerPlant array for the remaining valid ones! Any pointers?

EDIT: I tried out the suggestion as mentioned by the post below and I do get an error as shown in the screenshot:

在此处输入图片说明

Why is this? Is is complaining that PowerPlant is an interface and I need to provide values for the properties when I create a new instance of it?

Assuming that your api service returns an array of objects, which can be considered as PowerPlant object, here is what you can do.

powerPlants: PowerPlant[] = []; //initialize the array.

allPowerPlants(onlyActive: boolean = false, page: number = 1): void {
    const self = this;
    const path = `$/powerPlants?onlyActive${onlyActive}&page${page}`;
    this.apiService.get(path).subscribe(
        powerplants:any[] => {
            powerplants.forEach(item=>{
                if(isPowerPlant(item)){
                    // cast the item as PowerPlant
                    self.powerPlants.push(item as PowerPlant);
                }
           }); 
        },
        err=> {
            // handle error
        });
}

// define the type guard
isPowerPlant(item:any):item is PowerPlant {
    // check for the required properties of PowerPlant here and return true/false.
    // example:
    return item["powerplantProp1"] && item["powerplantProp2"];
}

Additionally, if your api service is not generic, then you may choose to return Observable<PowerPlant[]> from the get method instead of Observable<any> . To do this, you can use (res: Response) => res.json() as PowerPlant[] . However, this is just for the typing purpose.

References:

  1. https://scotch.io/tutorials/angular-2-http-requests-with-observables
  2. https://basarat.gitbooks.io/typescript/docs/types/typeGuard.html

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM