3

I have the following method in my Typescript!

allPowerPlants(onlyActive: boolean = false, page: number = 1): PowerPlant[] {
    const params: string = [
      `onlyActive=${onlyActive}`,
      `page=${page}`
    ].join('&');
    const path = `${this.allPowerPlantsURL}?${params}`;
    this.apiService.get(path).map(
      powerplants => {
        powerplants.map(item => {
          if (this.isPowerPlant(item)) {
            // make the item an instance of PowerPlant
            this.powerPlants.push(item as PowerPlant);
          }
      });
    },
    err => {
        console.log('oops **** some error happened');
      // handle error
    });
    console.log('powerplants obtained is *****************+ ');
    console.log(this.powerPlants);
    return this.powerPlants;
  }

My get method looks like this:

import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { Headers, Http, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class ApiService {
  loading: boolean;
  data: Object;
  constructor(
    private http: Http,
  ) {}


    get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> {
        console.log('sending request to ' + `${environment.api_url}${path}`);
        return this.http.get(`${environment.api_url}${path}`, { search: params })
          .catch(this.formatErrors)
          .map((res: Response) => {
            console.log('response as json is ' + res.json());
            res.json();
        });
      }
}

My isPowerPlant method looks like this:

isPowerPlant(item: any): item is PowerPlant {
    // check for the required properties of PowerPlant here and return true/false.
    // example:
    console.log('in the static method');
    const vvvv = item['maxPower'] && item['minPower'];
    console.log(vvvv);
    return vvvv;
  }

I was expecting to see some data in the console.log('response as json is '), but strangely it prints nothing! The request is not even making it to the server!

However, when I change my allPowerPlants method to not map over the get method, but instead subscribe like below:

this.apiService.get(path).subscribe(...)

I can see some data being fetched from the server as I see from my server logs that the request is being served.

I want to do the following:

I want allPowerPlants to return me an array of PowerPlants which is defined as below:

export interface PowerPlant {
  powerPlantId: number;
  powerPlantName: string;
  minPower: number;
  maxPower: number;
  powerPlantType: string;
  rampRateInSeconds?: number;
  rampPowerRate?: number;
}

Now since my get method is an Observable, I'm seeing that my Angular app is making tons and tons of calls to the server as it can be see from my server logs:

[info] application - GET /powerPlants?onlyActive=false&page=1 took 3192ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2974ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2701ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2682ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2885ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2920ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2552ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2564ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2598ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2612ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2615ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2621ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2636ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2609ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2701ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2544ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2588ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2532ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2586ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2570ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2652ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2624ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2661ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2618ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2611ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2624ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2620ms HTTP status >> 200

This is the actual data that my server sends:

[ {
  "powerPlantId" : 1,
  "powerPlantName" : "Organization-001",
  "minPower" : 20,
  "maxPower" : 100,
  "powerPlantType" : "OnOffType"
}, {
  "powerPlantId" : 2,
  "powerPlantName" : "Organization-001",
  "minPower" : 100,
  "maxPower" : 800,
  "rampPowerRate" : 100,
  "rampRateInSeconds" : 100,
  "powerPlantType" : "RampUpType"
}, {
  "powerPlantId" : 3,
  "powerPlantName" : "Organization-002",
  "minPower" : 200,
  "maxPower" : 400,
  "rampPowerRate" : 50,
  "rampRateInSeconds" : 50,
  "powerPlantType" : "RampUpType"
}, {
  "powerPlantId" : 4,
  "powerPlantName" : "Organization-002",
  "minPower" : 400,
  "maxPower" : 800,
  "powerPlantType" : "OnOffType"
} ]

How do I make my allPowerPlants just call my server only once but at the same time dealing with the Observable result from the get method?

This is how I make use of the data in my HTML:

<div class="ui grid posts">
  <app-powerplant
    *ngFor="let powerPlant of allPowerPlants()"
    [powerPlant]="powerPlant">
  </app-powerplant>
</div>
2
  • you never said what this.http is.... is it the new HttpClient or is it the old Http? Commented Aug 30, 2017 at 10:54
  • I have updated my post! Commented Aug 30, 2017 at 10:56

2 Answers 2

3

Here's a snippet of your code calling the data from the server

this.apiService.get(path).map(
      powerplants => {
       ...
          }

Stop right there. The reason there is no data is that you didn't subscribe to it! You should do this

this.apiService.get(path).subscribe(
      powerplants => {
        this.powerPlants = powerplants
        //remove the mapping. you can do it in your service.
    },
    err => {
        console.log('oops **** some error happened');
      // handle error
    });

And in your service

get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> {
        console.log('sending request to ' + `${environment.api_url}${path}`);
        return this.http.get(`${environment.api_url}${path}`, { search: params })
          .catch(this.formatErrors)
          .map((res: Response) => {
            <PowerPlant[]> res.json();
        });
      }

Note that my mapping could be wrong because you didn't show the actual value of the returned data.

Hope this helps.

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

7 Comments

I have edited my post to show the array that I get from the server
Ok Still it seems not to map the data! When I console.log(this.powerPlants) in my allPowerPlants method, I see it as undefined
@sparkr kindly check if you define your interface correctly. I.e in your interface, you define id while in the data it is powerPlantId, also you define orgName while the returned data has no property with orgName. Let me know if there's still an error
I updated my post with the correct field names! Yes, still the data is not available in my service!
Could you also tell me how I could avoid my Angular making so many calls? I guess I can convert my Observable into a Promise, but how do I get the value out of the Promise? I'm calling this function allPowerPlants like it can be seen in my updated post above!
|
2

OK, there are plenty of examples online on how to deal with http requests, tons on here....

usually you have a service with a get method dont ever use reserve words like GET to call your method ... in your case would be getAllPowerplants

in your case, the API service looks fine (except for the method name)

then on the component, you would have something like this

this.apiService.getAllPowerplants.subscribe(data => {
  console.log(data);
});

and obviously subscribe to it only once (ngOnInit is a good place) to put it

1 Comment

I think you missed my point! I'm subscribing only once, but I do not understand as to why the call is being made many times to the backend server!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.