kazik waraksa
kazik waraksa

Reputation: 21

Cannot read property of undefined, Typescript

I'm having issues with creating a class function with optional parameters. I'm plagued with the following error and since I'm a new comer to typescript I'm not really sure as to what I have to change in my code to fix it. This code works perfectly fine in an earlier project written in JS only.

It specifically highlights the getRequestOptions, when I go check it in base-service.ts in the browser error.

08:32:12.755 client.ts:22 [vite] connecting...
08:32:13.067 client.ts:52 [vite] connected.
08:32:17.043 locales-service.ts:7 getting locales
08:32:17.048 base-service.ts:19 get /Api/GetLocales/ undefined undefined undefined
08:32:17.288 base-service.ts:21 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'getRequestOptions')
    at request (base-service.ts:21)
    at getLocales (locales-service.ts:9)
    at setup (locale-selector.vue:22)
    at callWithErrorHandling (runtime-core.esm-bundler.js:6737)
    at setupStatefulComponent (runtime-core.esm-bundler.js:6346)
    at setupComponent (runtime-core.esm-bundler.js:6302)
    at mountComponent (runtime-core.esm-bundler.js:4224)
    at processComponent (runtime-core.esm-bundler.js:4199)
    at patch (runtime-core.esm-bundler.js:3791)
    at mountChildren (runtime-core.esm-bundler.js:3987)

And my code

base-service.ts

    import axios from '@/plugins/axios'

    export default class BaseService {
    getRequestOptions(url:any, method:any, data?:any, params?:any , customHeaders?:any) {
      const headers = {
        ...customHeaders
      }

      return {
        url:url,
        method:method,
        data: data,
        params: params,
        headers: headers,
      }
    }

    async request(method:any, url:any, data?:any, params?:any, headers?:any) {
        console.log(method,url,data,params,headers)

        const options = this.getRequestOptions(method, url, data, params, headers)

        try {
            console.log(options)
            const response = await axios(options)
            console.log("Getting response from api")
            console.log(response)
            if (response.status === 200) {
                return response.data
            }
        } catch (error) {
            console.log(error)
        }
    }
}

locales-service.ts

import BaseService from '../base-service'
//?Import models in the future
//import {  } from '@/common/models'

class LocaleServ extends BaseService {
    async getLocales() {
        console.log("getting locales")

        let result = await super.request(
                'get',
                '/Api/GetLocales/'
                )
        
        console.log(result)
        return result
    }
}

export const LocaleService = new LocaleServ()

Any help would be greatly appreciated

Edit:

<script lang="ts">
import { ref } from 'vue'
import { defineComponent } from 'vue'
import CountryFlag from 'vue-country-flag-next'
import { LocaleService } from '@/services'

export default defineComponent({
    name: 'LocaleSelector',
    components: {
        CountryFlag
    },

    setup () {
        const { getLocales } = LocaleService
        const data = getLocales()

        return {
            data:data
    }
  }
})
</script>

And then in the component I call it with {{data}}

Upvotes: 1

Views: 4327

Answers (1)

kazik waraksa
kazik waraksa

Reputation: 21

The issue lied in the way I called the destructured getLocales() method from LocaleService in locale-service.vue

I noticed that this was undefined after attaching a debugger. According to this article, destructuring it caused it to lose it's context. Therefore when I called getLocales() in base-service.ts, this was undefined.

Simple work around to fix the, caused due to inexperience, problem was to turn.

const { getLocales } = LocaleService
    const data = getLocales()

into

const data = LocaleService.getLocales()

Upvotes: 1

Related Questions