遍历可观察对象提供的对象数组,并为每个object.id调用http请求。

时间:2019-04-11 08:55:30

标签: angular typescript observable

通过组件ngOnInit方法中的Angular路由,我通过可观察的方式获得了流派ID,在该可观察的范围内,我调用了一种方法,该方法使用的服务会发出HTTP请求。

  this.movies: Movie[];

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      this.movieService.getMoviesByGenres(id).subscribe( response => {
        this.movies = response['results'];
      });
    });
  }

它返回此:

   "results": [
    {
      "vote_count": 664,
      "id": 287947,
      "video": false,
      "vote_average": 7.4,
      "title": "Shazam!",
      .
      .
      .
    },
    {
      "vote_count": 3623,
      "id": 299537,
      "video": false,
      "vote_average": 7.2,
      "title": "Captain Marvel",
      .
      .
      .
    }, ...
   ]

返回的是没有强制转换的电影,因此我需要通过为第一个请求返回的每个电影调用另一个HTTP请求并将第二个强制转换信息推送到movies[i].cast数组来为该电影请求强制转换。

所以基本上我想要的是这样的

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      this.movieService.getMoviesByGenres(id).subscribe( response => {
        this.movies = response['results'];
      });

      //pesudo code
      foreach(this.movies as movie) {
             this.movies[current element].casts = 
                  this.movieService.getCastByMovieId(movie.id);
      }
    }); 
  }

按类型获取电影,当结果到达时,遍历movies[]数组,并调用方法以获取电影ID的演员,并将演员添加到电影的casts: string []属性。然后返回this.movies: Movies[],现在它也包含演员表。

3 个答案:

答案 0 :(得分:1)

在Angular中工作时,您还可以利用RxJS的强大功能,例如以下内容

public ngOnInit(): void {
  this.route.paramMap.subscribe(param => {
    let id = +param.get('id');

    this.movieService.getMoviesByGenres(id).pipe(
      map(response => response['results']),
      mergeMap((movies: any[]) => {
        return forkJoin(
          movies.map(movie => {
            return this.movieService.getCastByMovieId(movie.id)
              .pipe(
                map((res: any) => {
                  movie.cast = res;
                  return movie;
                })
              );
          })
        )
      }))
      .subscribe(movies => {
        // Your logic here
      });
  })
}

基本上,您首先获取电影,然后将结果通过forkJoin传递,forkJoin一起执行所有请求,并保持顺序,将结果添加到movie.cast并最后返回完整的数组。这样,您还知道执行完成的时间。

请记住,如果forkJoin中的请求失败,则整个执行都会失败,因此您应该专门针对每个请求处理错误。

答案 1 :(得分:0)

您可以尝试以下操作:

ngOnInit() {
    const self= this; 
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      self.movieService.getMoviesByGenres(id).subscribe( response => {
        self.movies = response['results'];
        for(let movie of self.movies){
            self.movieService.getCastByMovieId(movie.id).subscribe((result)=>{
               self.movies[current element].casts = result;
           });
        }
      });
    }); 
  }

我将self用作变量是因为内部服务的上下文不同于组件。简而言之,“ this”的唯一区别在于服务和组件。

注意:在movieService中,使您返回HTTP请求,否则它将不返回Observable,因此组件将无法订阅它。

答案 2 :(得分:0)

我们可以通过像这样的端点请求来循环遍历数组

在 Ts 文件中

  let listToUpdate = [{...}, {...},...];

this.serviceObj.postData(listToUpdate).subscribe(
    response => console.log(response),
    error => console.error(error),
    () => console.info("All requests done") 
);

服务中的文件:

import { from } from "rxjs";
import { concatMap } from "rxjs/operators";

   ...

postData(listToUpdate){

  return  from(listToUpdate).pipe(
  concatMap(payload => this.http.post('http://localhost:4200/billing/balance-statement', payload))
  );
}