I have been working on an SPA with Angular 16, TypeScript and The Movie Database (TMDB).
I have made a component that displays movies by genre:
import { Component } from '@angular/core';
import { GenreResponse, Genre } from '../../models/Genre';
import { MovieResponse, Movie } from '../../models/Movie';
import { MovieService } from '../../services/movie-service.service';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-movies-by-genre',
templateUrl: './movies-by-genre.component.html',
styleUrls: ['./movies-by-genre.component.scss']
})
export class MoviesByGenreComponent {
public movieResponse!: MovieResponse;
public movies: Movie[] | undefined = [];
public genreResponse!: GenreResponse;
public genres: Genre[] | undefined = [];
public genreName: string | undefined = '';
constructor(
private activatedRoute: ActivatedRoute,
private movieService: MovieService
) { }
public getMoviesByGenre(): void {
// Get genre id (from URL parameter)
const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));
// Get genre name from genres array
this.movieService.getAllMovieGenres().subscribe((response) => {
this.genreResponse = response;
this.genres = this.genreResponse.genres;
if (this.genres && this.genres.length) {
let currentGenre = this.genres.find(genre => genre.id === genre_id);
if (currentGenre) {
this.genreName = currentGenre.name;
}
}
});
// Get movies by genre id
this.movieService.getMoviesByGenre(genre_id).subscribe((response) => {
this.movieResponse = response;
this.movies = this.movieResponse.results;
})
}
ngOnInit() {
this.getMoviesByGenre();
}
}
In the service used by the above component, I have:
import { environment } from '../../environments/environment';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { MovieResponse, Movie } from '../models/Movie';
import { GenreResponse } from '../models/Genre';
import { TrailerResponse } from '../models/Trailer';
@Injectable({
providedIn: 'root'
})
export class MovieService {
constructor(private http: HttpClient) { }
public getAllMovieGenres(): Observable<GenreResponse> {
return this.http.get<GenreResponse>(`${environment.apiUrl}/genre/movie/list?api_key=${environment.apiKey}`);
}
public getMoviesByGenre(id: Number): Observable<MovieResponse> {
return this.http.get<MovieResponse>(`${environment.apiUrl}/discover/movie?api_key=${environment.apiKey}&with_genres=${id}`);
}
}
In the routing module, I have:
const routes: Routes = [
{
path: '',
component: HomePageComponent,
data: { title: 'Now playing', animation: 'isRight' },
},
{
path: 'by-genre/:id',
component: MoviesByGenreComponent,
data: { title: '', animation: 'isLeft' },
},
{
path: 'movie/:id',
component: MovieDetailsComponent,
data: { title: '', animation: 'isLeft' },
},
{
path: 'actor/:id',
component: ActorDetailsComponent,
data: { title: '', animation: 'isRight' },
},
{
path: '**',
component: NotFoundComponent,
data: { title: '', animation: 'isRight' },
},
];
From the routing module, unless the title
property in the data
object is empty, I display the page title in appapp.component.html
:
<div class="container">
<h1 *ngIf="title.length" class="page-title text-success mt-2 mb-3">{{ title }}</h1>
<router-outlet></router-outlet>
</div>
For the MoviesByGenreComponent
, I want to send the dynamically obtained genre name (the variable genreName
), from the component to the router and assign genreName
to the title
property.
The desired result:
Stackblitz
There is a stackblitz with all the code I have so far.
2
Answers
You can store the post title content on the service and use a function
getFullTitle
to always fetch the latest value, the only caveat for this approach is you need to ensure the service title be set to an empty string everytime the component gets destroyed!movie by genre.com.ts
app.com.html
app.com.ts
Stackblitz Demo
I have refactored your code in several places. The Stackblitz Demo has been updated accordingly. Most files contain comments on how you can further improve your code.
I didn’t delete your previous code so that you can compare it with the refactored version.
Check each file or search for new comments