Выполните итерацию по массиву объектов, предоставленных наблюдаемым, и вызовите http-запрос foreach object.id? - PullRequest
0 голосов
/ 11 апреля 2019

При маршрутизации в Angular в методе компонента ngOnInit я получаю идентификатор жанра по наблюдаемым, в пределах этой наблюдаемой я вызываю метод со службой, которая делает 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[] и вызов метода для полученияприведение к идентификатору фильма и добавление приведений к свойству фильма casts: string [].И верните this.movies: Movies[], который теперь также содержит приведения.

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Поскольку вы работаете в 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, которыйвыполняет запросы все вместе, сохраняя порядок, добавляя результат в movie.cast и возвращая полный массив в конце.Таким образом, вы также знаете, когда выполнение завершено.

Помните, что если запрос внутри forkJoin завершается неудачно, все выполнение завершается неудачно, поэтому вы должны обработать ошибку специально для каждого запроса.

0 голосов
/ 11 апреля 2019

Вы можете попробовать что-то вроде этого:

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 как переменную, потому что контекст внутреннего сервиса отличается от компонента. Короче говоря, Единственное для этого это отличается для услуг и компонентов.

Примечание. В вашем movieService вы должны вернуть HTTP-запрос, иначе он не вернет Observable и, следовательно, компонент не сможет подписать его.

...