web-dev-qa-db-fra.com

Appel d'un autre observable avec la réponse d'un autre en Angular 4

J'écris une application Angular 4 utilisant HttpClient qui affiche les horaires des films. Il y a 2 fichiers JSON où se trouvent les données: showtimes.json et movies.json.

// showtimes.json    
[{
"id": "2030c64ce72b4e4605cb01f2ba405b7d",
"name": "Arclight", // need to display this information
"showtimes": {
  "b4c2c326a4d335da654d4fd944bf88d0": [ // need to use this id
      "11:30 pm", "2:45 pm", "8:35 pm", "4:15 pm", "10:30 pm"
  ]
 } 
}]

// movies.json
[{
"b4c2c326a4d335da654d4fd944bf88d0": { // to retrieve the title, rating, and poster
  "title": "Fifty Shades Darker", // needs to be displayed
  "rating": "R", // needs to be displayed
  "poster": "https://dl.dropboxusercontent.com/s/dt6wgt92cu9wqcr/fifty_shades_darker.jpg" // needs to be displayed
}
}]

J'ai un service qui peut récupérer le title et name du théâtre. Mais maintenant, je dois utiliser la valeur de l'objet showtimes pour afficher le nom de titre correct. Comme tu vois b4c2c326a4d335da654d4fd944bf88d0 est l'identifiant du titre du film et peut être récupéré à partir du movies.json fichier.

Jusqu'à présent, c'est ma composante

ngOnInit() {
  this._moviesDataService.getShowtimes()
  .subscribe(res => this.results = res)
}

Et c'est mon service.

getShowtimes (): Observable<ShowTimes> {
  return this._http.get<ShowTimes>(this._showtimesURL)
}

Ma question est de savoir comment récupérer le title du film en utilisant son identifiant? Cela nécessiterait-il deux observables enchaînés? Aurais-je besoin de parcourir le tableau des films et .filter il?

J'ai inclus un exemple de ce que j'essaye de construire Example

8
Kim Merino

Habituellement, lorsque vous en avez un observable et que vous devez saisir quelque chose. et retournez un Observable différent, vous pouvez utiliser switchMap:

ngOnInit() {
    this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            const id = Object.keys(res[0].showtimes)[0]; // assuming you have one element in your array and you want the first id from showtimes
            return this.getMovies(id); // assuming, you have a separate method that returns the movies
        })
        .subscribe(res => this.results = res)
}

MISE À JOUR

Étant donné que vous avez besoin des résultats des deux observables, mais aussi des résultats du premier pour demander le second, voici une idée de la façon dont vous pouvez le faire:

ngOnInit() {
    this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            const showtimes = res[0].showtimes;
            const id = Object.keys(showtimes)[0];

            return Observable.Zip(
                this.getMovies(id),
                Observable.of(showtimes[id])
            );
        })
        .subscribe(([movies, showtimes]) => {
            this.results.movies = movies; // or assign it to some other property
            this.results.showtimes = showtimes; // and use in the template
        }
12
Boris Lobanov

Je pense que parce que vous devez récupérer les titres de tous les films, vous devez enchaîner le tableau d'ID dans la réponse de la première demande, en une série de demandes de titres de films. quelque chose comme ceci: (en supposant que vous avez une méthode comme getMovieTitle qui obtient les données d'un film en fonction de son identifiant et renvoie un observable)

this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            let resArray: any[] = res.map(
                    item=>this._moviesDataService.getMovieTitle(
                        Object.keys(item.showtimes)[0]
            ))
            return Observable.merge(...resArray);
        })
        .subscribe(res => /*you will get a new res for each movie title here*/)

quelle Observable.merge oui, est-ce Turn multiple observables into a single observable. pour obtenir tous les résultats en un seul abonnement.

Remarque: n'oubliez pas d'affecter tout cela à un subscription et de le désinscrire à ngOnDestroy du composant (pour éviter les fuites de mémoire)

0
GHB