0

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:

enter image description here

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?

4
  • So how do you detect if there is any error in one of the array element? Commented Aug 26, 2017 at 14:00
  • I have no idea! Could you please help me with some pointers as to how I could do this? Commented Aug 26, 2017 at 18:04
  • I am little bit confused here. So some of the array element can have error, but you are not sure what can be considered as an error? As I am not an angular user, I would suggest you to use a callback in map method of this.apiService.get(path).map(), and assign the value passed on to the callback function to powerPlants; you can also use console.log inside the callback function to check whether everything is in order or not. Commented Aug 26, 2017 at 19:21
  • Error is some elements in the array that cannot be parsed into the model! Commented Aug 26, 2017 at 22:07

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried your suggestion, but looks like I've got an error! I have edited my post above!
@sparkr if PowerPlant is an interface then you can't instantiate it using new. In that case, self.powerPlants.push(item as PowerPlant);, or simply self.powerPlants.push(item); should also suffice.
Yes, PowerPlant is an interface in my case. Could you update your asnwer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.