I'm trying to subscribe to a service method that loads movie data from an API. Whenever the search is performed it searches for a different movie with a new ID. How do I subscribe to this from a component?
What I have done so far:
Service:
search(id): Observable<Movie> {
return this.http.get<Movie>('https://api.themoviedb.org/3/movie/' + id + '?api_key=KeyHidden&language=en-US');
}
Component:
export class TitleComponent implements OnInit {
movie: Movie;
constructor(public ms: MovieService) {}
ngOnInit() {
this.ms.search(this.ms.movieid).subscribe(data => this.movie = data);
}
}
Button performing search:
<button type="submit" mdbBtn (click)="ms.search(ms.movieid)" id="sub"> Search
</button>
Interface Movie:
export interface Movie {
title: string;
}
The search button potentially works, but you are not listening to the result.
You do a subscribe in ngOnInit
, but that by itself only gets the value once (with undefined id, which throws the error).
What you probably want, is to set up an observable in the service (an actual property) and upon button click you than call search
and in there you push the result of the http to that observable with .next(value)
. That way the component will be notified about the result.
Something along the lines:
MovieService:
private _movie$: BehaviourSubject<Movie> = new BehaviorSubject(null);
movie$ = this.movie$.asObservable();
search(id) {
this.http.get<Movie>(...).pipe(take(1)).subscribe(data => this.movie$.next(data));
}
TitleComponent
movie: Movie;
private terminate$: Subject = new Subject();
ngOnInit() {
this.ms.movie$.pipe(takeUntil(terminate$)).subscribe(data => this.movie = data);
}
ngOnDestroy() {
terminate$.next();
terminate$.complete();
}
// You don't really show where the search-id comes from or how it is set, so here I assume it is passed in from the html
onSearch(id) {
this.ms.search(id);
}