I load a list of items from the db which are to be displayed to the user in a list. Each item is of a particular type, and depending on the type, I wish to show an icon next to it.
I've created a component to control the icon that will be shown. The component accepts the type sa a prop and renders the mdi-icon accordingly.
<div v-if="iconName !== ''">
<v-icon large color="blue-grey darken-2">
{{ iconName }}
</v-icon>
</div>
The value of iconName is provided either while mounting, or as a computed property - I tried both of these.
export default {
props: ["activityType"],
data() {
return {
iconType: this.activityType,
iconName: 'mdi-script-text-outline',
iconMapping: {
learning_material_video: "mdi-video",
learning_material_quiz: "mdi-head-question-outline",
learning_material_article: "mdi-script-text-outline",
},
};
},
methods: {},
mounted(){
this.iconName = this.iconMapping[this.iconType]
},
computed: {
// iconName() {
// return this.iconMapping[this.activityType]
// },
},
};
This renders perfectly fine and I can ignore and continue working on the next component but the error in the console is a bit worrysome.
Uncaught (in promise) Error: Icon value is undefined or null
at ReactiveEffect.eval [as fn] (icons.tsx?ff78:168:1)
at ReactiveEffect.run (reactivity.esm-bundler.js?89dc:167:1)
at ComputedRefImpl.get value [as value] (reactivity.esm-bundler.js?89dc:1101:1)
at Proxy.eval (VIcon.tsx?e5c2:53:1)
at renderComponentRoot (runtime-core.esm-bundler.js?d2dd:893:1)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?d2dd:5098:1)
at ReactiveEffect.run (reactivity.esm-bundler.js?89dc:167:1)
at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)
at flushJobs (runtime-core.esm-bundler.js?d2dd:394:1)
at flushJobs (runtime-core.esm-bundler.js?d2dd:409:1)
This has no effect in how the page looks or works but I'm worried if this might create issues later. I'm hardly 5 days in into Vue and I might be doing something wrong here. Is my code the right way to do it or can it be better?
ps. This is Vuetify-3.
You should use a safety guard:
<template>
<div>
<v-icon large color="blue-grey darken-2">{{ iconName }}</v-icon>
</div>
</template>
<script>
export default
{
name: 'MyCustomComponent',
props:
{
activityType:
{
type: String,
default: ''
}
},
computed
{
iconName()
{
return {
learning_material_video: "mdi-video",
learning_material_quiz: "mdi-head-question-outline",
learning_material_article: "mdi-script-text-outline",
}[this.activityType] || 'mdi-script-text-outline';
}
}
}