Reputation:
my code outputs everytime different numbers. Is this a proper way I am using it? Here is the code:
export class GetPlanetsService {
url='https://swapi.co/api/planets/?page=';
planets:Planet[]=[];
headers: HttpHeaders = new HttpHeaders()
.set('Accept', 'application/json');
constructor(private http:HttpClient) { }
getPlanet(pageIndex){
return this.http.get<Planets>(`${this.url}${pageIndex}`,{headers:this.headers});
}
getAllPlanets(){
let numberOfPages=7; // Tried to do it dynamically but got infinite loop
for(let j=1;j<=numberOfPages;j++){
this.getPlanet(j).subscribe(value=>{
for(let i=0;i<value.results.length;i++){
this.planets.push(value.results[i]);
if(j==numberOfPages && i==(value.results.length-1)){
console.log(this.planets); //There is outputted everytime different number
}
}
});
}
}
Have you got any tips and could you explain it in simple words? Regards
Upvotes: 2
Views: 73
Reputation: 2330
Ok there is deeper problemes here.
First, why are you trying to call the server 7 times in a row? What if I want page 200? You will make 200 Http requests? The server should return the entire list. It will increase performance and reduce complexity on client side.
Also, why getAllPlanets()
return void
? It's not intuitive. Instead, getAllPlanets()
should return Observable<Planet[]>
. All functions should either return of modify (it's part of the CQS principle) here the purpose it to return data so you can't notify your object state e.g. this.planets.push(value.results[i])
. What if a invoke the function twice? Then, this.planets
will contain the result of both requests.
Upvotes: 0
Reputation: 3386
You can use forkJoin
for this, Dont forget to include
import { forkJoin } from 'rxjs';
forkJoin waits for each HTTP request to complete and group’s all the observables returned by each HTTP call into a single observable array and finally return that observable array.
getPlanet(pageIndex) {
return this.http.get < Planets > (`${this.url}${pageIndex}`, {
headers: this.headers
});
}
getAllPlanets() {
const response = [...Array(7).keys()].map(i => this.getPlanet(i));
return forkJoin(response);
}
in your component you can call getAllPlanets
this.getPlanetsService.getAllPlanets()
.subscribe(res => {
console.log(res);
}, err => {
console.log(err);
});
Upvotes: 2