2

I try to start using typescript with VueJS but I encounter a TypeError problem.

In my App.vue, I have a array of Gallery class as a class property. In the created hook, I call a webservice to fill this array. Once I fill it, when I log it, I have Objects and not Gallery instances. And if I try to call a function on a Gallery instance, it fails. I think the problem is more a TS problem than a Vue problem.

I can't understand why I have actually an array of Object when I say everywhere I need an array of Gallery.

If anyone has a idea to help me, I'm more than interrested.

Thanks for reading. I paste you all my code below.

Have a nice day ;)

Dimitri

App.vue

<template>
    <div>
        <CvGallery v-for="(gallery, i) in galleries" gallery="gallery" :key="i"></CvGallery>
    </div>
</template>

<script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    import CvGallery from "@/components/CvGallery.vue";
    import Gallery from "@/models/Gallery";
    import axios from "@/axios/axios-creatiview"

    @Component({
        components: {
            CvGallery
        },
    })
    export default class App extends Vue {
        private galleries: Gallery[] = [];

        created() {
            axios.get('').then(response => {
                console.log(response.data);
                response.data.forEach((galleryJson: {id: number; name: string; description: string}) => {
                    const gallery = new Gallery(galleryJson.id, galleryJson.name, galleryJson.description);
                    this.galleries.push(gallery);
                    console.log(typeof gallery);
                });
            });
        }
    }
</script>

<style>
</style>

Gallery.ts

export default class Gallery{
    private readonly id: number;
    private readonly name: string;
    private readonly description: string;

    constructor(id: number, name: string, description: string) {
        this.id = id;
        this.name = name;
        this.description = description;
    }

    getId(){
        return this.id;
    }

    getName(){
        return this.name;
    }

    getDescription(){
        return this.description;
    }
}

CvGallery.vue

<template>
    <div class="gallery">
        <p>Gallery</p>
        <p>{{ gallery.getDescription() }}</p>
    </div>
</template>

<script lang="ts">
    import {Component, Vue, Prop} from 'vue-property-decorator'
    import Gallery from "@/models/Gallery";
    @Component
    export default class CvGallery extends Vue{
        @Prop() private gallery!: Gallery;
    }
</script>

<style scoped>
    .gallery{
        background-color: #222222;
        color: #DDDDDD;
    }
</style>

log

16:16:42,658 [HMR] Waiting for update signal from WDS... log.js:24
16:16:42,771
(3) […]
​
0: Object { id: 1, name: "DisneyWorld", description: "First trip to DisneyWorld Florida!" }
​
1: Object { id: 2, name: "Europapark", description: "The best German park" }
​
2: Object { id: 3, name: "Disneyland Paris", description: "A lot of walkthrough attractions" }
​
length: 3
​
<prototype>: Array []
App.vue:23
16:16:42,772 object 3 App.vue:27
16:16:42,774 [Vue warn]: Error in render: "TypeError: _vm.gallery.getDescription is not a function"

found in

---> <CvGallery> at src/components/CvGallery.vue
       <App> at src/App.vue
         <Root> vue.runtime.esm.js:619
16:16:42,774 TypeError: "_vm.gallery.getDescription is not a function"
    render CvGallery.vue:7
    VueJS 20
vue.runtime.esm.js:1888
16:16:42,775 [Vue warn]: Error in render: "TypeError: _vm.gallery.getDescription is not a function"

found in

---> <CvGallery> at src/components/CvGallery.vue
       <App> at src/App.vue
         <Root> vue.runtime.esm.js:619
16:16:42,775 TypeError: "_vm.gallery.getDescription is not a function"
    render CvGallery.vue:7
    VueJS 20
vue.runtime.esm.js:1888
16:16:42,776 [Vue warn]: Error in render: "TypeError: _vm.gallery.getDescription is not a function"

found in

---> <CvGallery> at src/components/CvGallery.vue
       <App> at src/App.vue
         <Root> vue.runtime.esm.js:619
16:16:42,776 TypeError: "_vm.gallery.getDescription is not a function"
    render CvGallery.vue:7
    VueJS 20
vue.runtime.esm.js:1888

4
  • Try decorating your container div with v-if like this : <div v-if="galleries"> <CvGallery....> </div> Since your data loaded async it will be empty when your view created initially. Commented Feb 15, 2020 at 14:55
  • Please, include the error as text. The problem should be intelligible without navigating to external links and doesn't require to be represented as an image. Commented Feb 15, 2020 at 15:04
  • 1
    @Eldar I try but it changes nothing. I think Vue logic is ok because my "galleries" class property is reactive. Also, in the error stack, we have the same error 3 times, like the number of elements of my array. Thanks for your help :) Commented Feb 15, 2020 at 15:21
  • @EstusFlask Yep sorry I just didn't know how to makes this clear. After your comment, I discover there is a right click option in firefox console to do that. I will not forget next time thanks Commented Feb 15, 2020 at 15:41

1 Answer 1

2

This is not TypeScript problem because the error occurs at runtime, it would be the same in JavaScript.

vm.gallery.getDescription is not a function error means that gallery is defined, otherwise it would be Cannot read property 'getDescription' of undefined. It also means that gallery is not an instance of Gallery, otherwise there would be getDescription method.

Since there are no mistakes in created hook, the problem can be narrowed down to how gallery is passed to the component; it's a string value:

<CvGallery v-for="(gallery, i) in galleries" gallery="gallery" :key="i"></CvGallery>

Instead, it should be bound:

<CvGallery v-for="(gallery, i) in galleries" :gallery="gallery" :key="i"></CvGallery>
Sign up to request clarification or add additional context in comments.

2 Comments

You're welcome, glad it was that simple. Also, this is TS problem, in a way. The problem is that vue-property-decorator doesn't provide proper props typing features and requires to be asserted with gallery!: Gallery. If it were possible for typing system to determine that gallery prop is a string and not Gallery, the problem could be revealed at compilation time. FWIW, Vue class components were abandoned, for properly typed TS check function components and composition API, vue-composition-api-rfc.netlify.com/api.html#definecomponent
Nice thanks for the complementary ansmwer. I gonna search and chage my code in that way. It's true that I'm asking me "why Am I using TS if it can't tell me when I'm giving the wrong type..."

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.