I am working on an SPA with Vue 3, TypeScript and The Movie Database (TMDB).
The app displays list of movie cards.
In the MoviesList component (srccomponentsMoviesList.vue
), I have:
<template>
<div class="row list">
<div v-for="movie in movies" :key="movie.id" class="col-xs-12 col-sm-6 col-lg-4 col-xl-3">
<MovieCard :movie="movie" :genres="genres" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import axios from 'axios';
import env from '../env';
import MovieCard from './MovieCard.vue';
export default defineComponent({
name: 'MoviesList',
components: {MovieCard},
props: {
listType: String
},
data() {
return {
pageTitle: "Now Playing",
movies: [],
genres: [],
}
},
mounted() {
this.getMovies();
this.getGenres();
},
methods: {
getMovies() {
axios.get(`${env.api_url}/movie/${this.$props.listType}?api_key=${env.api_key}`).then(response => {
this.movies = response.data.results;
})
.catch(err => console.log(err));
},
getGenres() {
axios.get(`${env.api_url}/genre/movie/list?api_key=${env.api_key}`).then(response => {
this.genres = response.data.genres;
console.log(this.genres);
})
.catch(err => console.log(err));
}
}
});
</script>
In the MovieCard component (srccomponentsMovieCard.vue
), I have:
<template>
<div class="movie card">
<div class="thumbnail">
<img :src="`https://image.tmdb.org/t/p/w500/${movie.backdrop_path}`" :alt="movie.title" class="img-fluid" />
</div>
<div class="card-content">
<h2 class="card-title">{{ movie.title }}</h2>
<p class="card-desc">{{ movie.overview }}</p>
<span :title="`Score: ${movie.vote_average}`" class="score d-flex">{{ movie.vote_average }}</span>
</div>
<div class="card-footer">
<p class="m-0 release">Release date: {{ dateTime(movie.release_date) }}</p>
<p class="m-0 pt-1">
<a class="genre" v-for="genre in movie.genre_ids" :key="genre.id">
{{ getGenreName(genre) }}
</a>
</p>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import moment from 'moment';
export default defineComponent({
name: 'MovieCard',
props: {
movie: {
type: Object,
required: true
},
genres: {
type: Object,
required: true
}
},
methods: {
dateTime(value: any) {
return moment(value).format('MMMM DD, YYYY');
},
getGenreName(gid: number) {
if (this.genres[gid]) {
if (this.genres[gid].name.length) {
return this.genres[gid].name;
}
}
}
},
});
</script>
The problem
I use the below condition to make sure no empty genre conrainers are displayed:
if (this.genres[gid].name.length) {
return this.genres[gid].name;
}
For a reason I have been unable to understand, this fails, as seen below.
Questions
- What is my mistake?
- What is the most reliable way to get the desired result?