I am currently working with 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;
}
The get method in my codebase is structured 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();
});
}
}
This is what my isPowerPlant method looks like:
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;
}
Upon running the above code, I noticed that the response was not being printed in the console log. The server logs also showed no indication of the request being sent.
To rectify this issue, I modified the allPowerPlants method to utilize the subscribe function instead of map:
this.apiService.get(path).subscribe(...)
By making this change, I was able to confirm data retrieval from the server by checking the server logs.
My goal is to have the allPowerPlants method return an array of PowerPlants defined as shown below:
export interface PowerPlant {
powerPlantId: number;
powerPlantName: string;
minPower: number;
maxPower: number;
powerPlantType: string;
rampRateInSeconds?: number;
rampPowerRate?: number;
}
However, due to the use of Observables, multiple server calls were being made by my Angular app resulting in unnecessary requests as evidenced by the 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
...
The response data from the server includes the following information:
[ {
"powerPlantId" : 1,
"powerPlantName" : "Organization-001",
...
} ]
How can I optimize the allPowerPlants method to make a single server call while handling the Observable result effectively?
In my HTML template, I utilize the data fetched as follows:
<div class="ui grid posts">
<app-powerplant
*ngFor="let powerPlant of allPowerPlants()"
[powerPlant]="powerPlant">
</app-powerplant>
</div>