nuxt-community/hackernews-nuxt-ts

Use axios types in vuex store

P4sca1 opened this issue ยท 9 comments

I am currently rewriting my vue project using typescript and this project is a great reference, thank you!

I noticed that you are using nuxt-axios and in your vuex store you are doing this:
(this as any).$axios
I am wondering whether there is any better way that automatically detects what is available in this and also utilize nuxt-axios typings?

Same goes for using this.$router for example in vuex store. Would be really great to get typing support there.

Closing, as this issue has been discussed in the official nuxt discord.

@P4sca1 I'm trying to find a solution to this as well. Do you have a link to the discussion in the Nuxt Discord? Thanks.

@kevinmarrec told me that it is planned to extend default typings, maybe with a class based approach but not yet possible.
I donโ€™t know the current status.

@satindar @P4sca1

Since nuxt-community/axios-module#227, using this.$axios now works without having to cast as this as any as done in https://github.com/nuxt-community/hackernews-nuxt-ts/blob/master/store/index.ts.

Don't forget to add @nuxtjs/axios in your tsconfig.json under the types compiler option.

Is there any way to make this work with vuex-module-decorators ?

@kevinmarrec My tsconfig is as follows but I am still getting this axios type error.

{
    "compilerOptions": {
        "target": "es2018",
        "module": "esnext",
        "moduleResolution": "node",
        "lib": [
            "esnext",
            "esnext.asynciterable",
            "dom"
        ],
        "esModuleInterop": true,
        "allowJs": true,
        "checkJs": true,
        "sourceMap": true,
        "strict": true,
        "noEmit": true,
        "baseUrl": ".",
        "paths": {
            "~/*": [
                "./*"
            ],
            "@/*": [
                "./*"
            ]
        },
        "types": [
            "@types/node",
            "@nuxt/types",
            "@nuxtjs/axios"
        ]
    },
    "exclude": [
        "node_modules"
    ]
}

My .eslintrc.js

module.exports = {
    root: true,
    env: {
        browser: true,
        node: true
    },
    extends: [
        '@nuxtjs/eslint-config-typescript',
        'plugin:nuxt/recommended'
    ],
    // add your custom rules here
    rules: {
        "indent": ["error", 4],
        "vue/html-indent": ["error", 4],
        "vue/script-indent": ["error", 4],
        "vue/multiline-html-element-content-newline": ["error", {
            "ignoreWhenEmpty": true,
            "ignores": ["pre", "textarea"],
            "allowEmptyLines": true
        }],
        "vue/html-self-closing": ["error", {
            "html": {
                "void": "any",
                "normal": "always",
                "component": "any"
            }
        }],
        "no-console": 0
    }
}

This is my function, have to use (this as any) as a workaround.

async getDescription () {
    try {
        const res = await (this as any).$axios.get('/MyApi/GetDescription', {
            params: { name: this.barcode }
        })

        const data = res.data

        this.description = data

        this.showScanner = false
    } catch (err) {
        console.log(err.response)
    }
}

@rcheung9 What is your this ? Where is defind your functio. I'm missing context to help you.
Also, is it related to this project ?

@kevinmarrec It's in a .vue component so this is the Vue context.

<script lang="ts">
import Vue from 'vue'
import { Barcode, BarcodePicker, ScanSettings, configure, CameraSettings } from 'scandit-sdk'

export default Vue.extend({
    name: 'Index',
    data (): {
        barcode: any
        description: string
        value: number | null
        showScanner: boolean
        scanInterval: number
        barcodePicker: BarcodePicker
        } {
        return {
            barcode: null,
            description: '',
            value: null,
            showScanner: false,
            scanInterval: 1000,
            barcodePicker: {} as BarcodePicker
        }
    },
    computed: {
        scannerWidth () {
            let width = window.innerWidth

            const el = document.querySelector('.scandit-barcode-picker')

            if (el != null) {
                width = el.clientWidth
            }

            return width
        },
        isInstalledApp () {
            if (window.matchMedia('(display-mode: standalone)').matches) {
                return true
            } else {
                return false
            }
        }
    },
    watch: {
        showScanner () {
            if (this.showScanner && this.barcodePicker.isScanningPaused) {
                this.barcodePicker.resumeScanning()
            } else if (!this.showScanner) {
                this.barcodePicker.pauseScanning()
            }
        },
        barcode () {
            this.getDescription()
        }
    },
    beforeMount () {
        if (this.isInstalledApp || window.location.hostname === 'localhost') {
            this.initScandit()
        }
    },
    mounted () {
        if (this.isInstalledApp || window.location.hostname === 'localhost') {
            this.createScandit()
        }
    },
    methods: {
        initScandit () {
            configure(process.env.VUE_APP_SCANDIT_LICENSE as string, {
                engineLocation: 'https://cdn.jsdelivr.net/npm/scandit-sdk/build'
            })
        },
        createScandit () {
            const el = document.getElementById('scandit')

            if (el != null) {
                BarcodePicker.create(el, {
                    playSoundOnScan: true,
                    vibrateOnScan: true,
                    scanningPaused: true,
                    videoFit: BarcodePicker.ObjectFit.COVER,
                    cameraSettings: {
                        resolutionPreference: CameraSettings.ResolutionPreference.FULL_HD
                    }
                }).then((barcodePicker) => {
                    this.barcodePicker = barcodePicker

                    const scanSettings = new ScanSettings({
                        enabledSymbologies: [Barcode.Symbology.CODE128],
                        codeDuplicateFilter: this.scanInterval,
                        searchArea: {
                            x: 0,
                            y: 0.35,
                            height: 0.15,
                            width: 1
                        }
                    })

                    barcodePicker.applyScanSettings(scanSettings)
                    barcodePicker.setMirrorImageEnabled(false)

                    barcodePicker.on('scan', (scanResult) => {
                        this.barcode = scanResult.barcodes[0].data
                    })
                })
            }
        },
        mirror () {
            this.barcodePicker.setMirrorImageEnabled(!this.barcodePicker.isMirrorImageEnabled())
        },
        async getDescription () {
            try {
                const res = await (this as any).$axios.get('/DataApi/GetDescription', {
                    params: { name: this.barcode }
                })

                const data = res.data

                this.description = data

                this.showScanner = false
            } catch (err) {
                console.log(err.response)
            }
        },
        save () {}
    }
})
</script>