简体   繁体   中英

How to map returned Observable from Http call in Angular

The below code returns an empty array, and I'm having trouble understanding why. What is the standard practice for pushing objects to an array from a return Observable?

In jobServices.ts:

 getCities(city){
  return this.http.get(`http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=70d86e78cabf44f710fd89936c709750`)
 }

In Home.ts

cities = ["Atlanta", "Chicago", "New York", "Los Angeles", "San 
   Diego", "Athens", "Miami", "Nashville", "Austin", "Amsterdam", 
   "Paris" ]
citiesPayload = []



constructor(public jobService: JobService) { }

ngOnInit() {
    this.returnCities();
}

returnCities(){
    for (var i = 0; i < this.cities.length; i++){
        this.jobService.getCities(this.cities[i])
            .subscribe(city => {
                this.citiesPayload.push(city);
            });
        }
    console.log(this.citiesPayload)
}

Try something like this, you need to add the HTTP requests into an array then use an operator like forkJoin . Then you can subscribe to that newly returned stream.

import {
  forkJoin
} from 'rxjs';
class ExampleClass {
  cities = [
    "Atlanta",
    "Chicago",
    "New York",
    "Los Angeles",
    "San Diego",
    "Athens",
    "Miami",
    "Nashville",
    "Austin",
    "Amsterdam",
    "Paris"
  ];
  constructor(public jobService: JobService) {}




  ngOnInit() {
    this.returnCities()
  }

  returnCities() {
    const cityObservables = [];
    for (var i = 0; i < this.cities.length; i++) {
      cityObservables.push(this.jobService.getCities(this.cities[i]));
    }
    forkJoin(cityObservables).subscribe(resp => {
      // city data here
      console.log(resp);
    });
  }

  getCities(city) {
    return this.http.get(`http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=70d86e78cabf44f710fd89936c709750`)
  }
}

Adding a stackblitz-demo included are the suggestions of @RichardMatsen & @eric99.

import {
  Component,
  OnInit
} from '@angular/core';
import {
  HttpClient
} from '@angular/common/http';

import {
  Observable,
  forkJoin,
  of
} from 'rxjs';
import {
  catchError
} from 'rxjs/operators';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  todos: number[] = [1, 3, 5, 7, 9];
  viewValues: Todo[];

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.getTodos();
  }

  getTodos() {
    const todos = this.todos.map(t => this.http.get < Todo > (`https://jsonplaceholder.typicode.com/todos/${t}`));
    forkJoin(todos).pipe(catchError(err => of (err))).subscribe(resp => this.viewValues = resp);
  }
}


export interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

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