What could be triggering the "slice is not defined" error in this TypeScript and Vue 3 application?

I have been developing a Single Page Application using Vue 3, TypeScript, and the The Movie Database (TMDB) API.

In my src\components\MovieDetails.vue file, I have implemented the following:

<template>
  <div class="row">
    <div class="col-sm-4 col-md-3">
      <div class="poster-container text-center text-sm-start my-3">
        <img v-if="movie"
          :src="genericPoster"
          :alt="movie?.title"
          class="img-fluid shadow-sm"
        />
      </div>
    </div>

    <div class="col-sm-8 col-md-9">
      <h1 class="movie-title mt-4">{{ movie?.original_title }}</h1>

      <p v-if="movie?.genres.length">
        <strong class="pe-1">Genres:</strong>
        <span
          class="badge bg-secondary"
          v-for="genre in movie?.genres"
          :key="genre.id"
          >{{ genre.name }}</span
        >
      </p>

      <p v-if="movie?.vote_average" class="user-score">
        <strong>User Score:</strong>
        <span class="score" :class="movieQuality">{{
          Number(movie?.vote_average).toFixed(2)
        }}</span>
      </p>

      <div v-if="movie?.overview">
        <h2 class="section-title">Overview</h2>
        <p>{{ movie.overview }}</p>
      </div>

      <div v-if="movieTrailers.length" class="mb-3">
        <h2 class="section-title">Trailers</h2>
        <TrailerCarousel :movieTrailers="movieTrailers" />
      </div>

      <div v-if="movieCast.length" class="cast-container">
        <h2 class="section-title">Cast</h2>
        <div class="row">
          <div
            v-for="actor in movieCast.slice(0, 12)"
            :key="actor['id']"
            class="col-sm-3"
          >
            <ActorCard :actor="actor" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { useRoute } from "vue-router";
import env from "../env";
import { Movie } from "@/models/Movie";
import { Trailer } from "@/models/Trailer";
import { MovieCast } from "@/models/MovieCast";
import TrailerCarousel from "./TrailerCarousel.vue";
import ActorCard from "./ActorCard.vue";

export default defineComponent({
  name: "MovieDetails",

  components: {
    TrailerCarousel,
    ActorCard,
  },

  data: () => ({
    route: useRoute(),
    genericPosterBig: require('../assets/generic-poster.png'),
    movie: null as Movie | null,
    movieQuality: String as unknown | 'bad',
    movieCast: Array as unknown | MovieCast[],
    movieTrailers: Array as unknown | Trailer[]
  }),

  mounted() {
    this.getMovieDetails();
    this.getMovieTrailers();
    this.getMovieCast();
  },

  methods: {
    getMovieDetails() {
      this.$axios
        .get(
          `${env.api_url}/movie/${this.route.params.id}?api_key=${env.api_key}`
        )
        .then((response) => {
          this.movie = response.data;
          // Set the movie quality once it's retrieved
          this.setMovieQuality();
        })
        .catch((err) => console.log(err));
    },

    setMovieQuality() {
      if (Number(this.movie?.vote_average) >= 7) {
         this.movieQuality = 'good';
      } else if(Number(this.movie?.vote_average) < 7 && Number(this.movie?.vote_average) > 5.5) {
         this.movieQuality =  'average';
      } else {
         this.movieQuality =  'bad';
      }
    },

    getMovieTrailers() {
      this.$axios
        .get(
          `${env.api_url}/movie/${this.route.params.id}/videos?api_key=${env.api_key}`
        )
        .then((response) => {
          this.movieTrailers = response.data.results;
        })
        .catch((err) => console.log(err));
    },

    getMovieCast() {
      this.$axios
        .get(
          `${env.api_url}/movie/${this.route.params.id}/credits?api_key=${env.api_key}`
        )
        .then((response) => {
          this.movieCast = response.data.cast;
        })
        .catch((err) => console.log(err));
    },
  },

  computed: {
    genericPoster() {
      return !this.movie?.poster_path
        ? this.genericPosterBig
        : `https://image.tmdb.org/t/p/w500/${this.movie?.poster_path}`;
    },
  },

  watch: {
    "$route.params.id"() {
      this.getMovieDetails();
      this.getMovieTrailers();
      this.getMovieCast();
    },
  },
});
</script>

In the src\models\MovieCast.ts file:

export interface MovieCast {
    adult?: boolean;
    character?: string;
    name?: string;
    profile_path?: string;
}

Instead of the previous lines in the components:

movieCast: Array as unknown | MovieCast[]
movieTrailers: Array as unknown | Trailer[]

I initially had:

movieTrailers: [],
movieCast: [],

I decided to make this change to ensure a more strictly typed application.

The Issue

However, after making this update, the console error displayed is:

TypeError: _ctx.movieCast.slice is not a function

<div
    v-for="actor in movieCast.slice(0, 12)"
    :key="actor['id']"
    class="col-sm-3"
  >
    <ActorCard :actor="actor" />
</div>

A working demonstration of the app can also be found on Stackblitz.

Queries

  1. What could be the mistake I am making?
  2. What would be the most effective way to resolve this issue?

Answer №1

If you encounter an error when assigning a non-array, try logging the type to see what is being returned.

console.log('movieCast', response.data.cast)
this.movieCast = response.data.cast;

To avoid errors while your async value is undefined and calculating, use a conditional operator. You can also wrap the v-for in a v-if statement to check for undefined.

v-for="actor in movieCast?.slice(0, 12)"

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can you show me the steps to set a session in the front-end using Nuxt

I have successfully set the session using code on Postman. First: I set my session and it is functioning properly. const user = { name: 'afshin', }; req.session.user = user; res.status(200).send({data:req.session.user,status:200}); Second: No ...

Having trouble getting this.$set() to function properly with vue2.0 and Laravel integration

I'm currently attempting to store data in vue js and then display it on the view. This is my vue method: getVueItems: function(){ var vm = this; axios.get('/someuri').then(function(response) { vm.$set(this,'it ...

Searching for similar but not identical results using Knex.js

I am seeking a solution to retrieve similar posts without including the post itself. Here is my approach: export async function getSimilars(slug: string) { const excludeThis = await getBySlug(slug) const posts = await knex('posts') .whe ...

When using the imported function, a TypeError occurs: "... is not recognized as a valid function."

I often use a function across multiple files, and it works perfectly like this: import moment from 'moment'; let monthAsString = (month: number): string => { return moment().locale('de').month(month - 1).format("MMMM"); } config ...

Is it possible to add new values to a GraphQL query?

I am currently utilizing GraphQL and Typeorm in conjunction with an Oracle Database, specifically focusing on retrieving all data from a specific table. The query that is being executed is: SELECT "inventory"."id" AS "inventory_id", "inventory"."value" AS ...

The error message "TypeScript is showing 'yield not assignable' error when using Apollo GraphQL with node-fetch

Currently, I am in the process of implementing schema stitching within a NodeJS/Apollo/GraphQL project that I am actively developing. The implementation is done using TypeScript. The code snippet is as follows: import { makeRemoteExecutableSchema, ...

The event in Vue.js does not trigger for items that have been filtered out of the list

I currently have a list of items, each with a "complete" flag. Depending on the value of this flag, the item is displayed in either view A or view B. These items are fetched through an API request and then filtered client-side using a computed method based ...

Tips for adjusting column sizes in ag-grid

I'm a beginner with ag-grid and need some help. In the screenshot provided, I have 4 columns initially. However, once I remove column 3 (test3), there is empty space on the right indicating that a column is missing. How can I make sure that when a col ...

Guide on implementing Regular Expressions in Directives for validation in Angular 8

Managing 8 different angular applications poses its unique challenges. In one of the applications, there is a directive specifically designed for validating YouTube and Vimeo URLs using regular expressions. Unfortunately, once the RegExp is declared, ther ...

"I'm looking for a way to store and fetch TypeScript objects with PouchDB. Any suggestions on

As someone who is new to typescript and web development, I am eager to incorporate PouchDB into my typescript project to store my objects. Despite the lack of documentation, I am struggling to find the correct approach. I have created typescript objects t ...

Implementing TypeScript with styled components using the 'as' prop

I am in the process of developing a design system, and I have created a Button component using React and styled-components. To ensure consistency, I want all my Link components to match the style and receive the same props as the Button. I am leveraging t ...

unable to retrieve information from the redis cache

Attempting to retrieve data from cache using the readData function in the controller file. Encountering an issue where the someVal variable is initially undefined after calling readData, but eventually gets populated with data after receiving a callback ...

Error: Class cannot be loaded by React Webpack loader

I'm encountering an issue with my two typescript packages - a React application and an infrastructure package. The React app has a dependency on the infrastructure package (currently linked via npm). After adding a new class to the infrastructure pack ...

Submit Empty Form Data

In my NuxtJS application, I have multiple components that come together in one form. Below is the code snippets of each component: AppButton.vue <template> <button class="button" :class="btnStyle" :disabled="disabled" v-bind="$ ...

Issue: Unable to resolve all parameters for LoginComponent while implementing Nebular OAuth2Description: An error has occurred when attempting to

I have been attempting to utilize nebular oauth in my login component, following the documentation closely. The only difference is that I am extending the nebular login component. However, when implementing this code, I encounter an error. export class Lo ...

When transitioning to generics, the narrowing of types in TypeScript is sometimes lost

I am intrigued by this scenario where Test1 fails while Test2 succeeds. I wonder if there is a way to have Test1 pass without altering the generic signature: enum TableType { Shipment = "Shipment", Batch = "Batch", } type Test& ...

The API endpoint returns a 404 not found error on NextJS 14 in the production environment, while it functions correctly on the local

I am in the process of creating a small website using NEXT JS 14. On my website, there is a contact us page that I have been working on. In the GetInTouch.tsx file, I have the following code: <Formik initialValues={{ ...

Encountering a TypeScript type error when returning a promise from a function

I currently have a scenario in which there is a function that checks if user whitelisting is required. If not, it calls the allowUserToLogin function. If yes, it then checks if a specific user is whitelisted. If the user is not whitelisted, an error is thr ...

Discover the Primevue DataTable feature that enables dynamic column and column grouping functionality, with the added bonus of gridlines disappearing as you scroll down

I am currently utilizing the PrimeVue DataTable feature with dynamic column and column grouping. Initially, when the table loads, everything appears to be great - gridlines are visible, columns freeze, scrollable functionality is working as expected. htt ...

Enhance user experience with Angular Material and TypeScript by implementing an auto-complete feature that allows

Currently facing an issue with my code where creating a new chip triggers the label model to generate a name and ID. The problem arises when trying to select an option from the dropdown menu. Instead of returning the label name, it returns an Object. The ...