I'm using the following script to render a Dropdown using PrimeVue:
<template lang="pug">
Dropdown#tag(v-model="tag" :options="tags")
</template>
<script setup>
import axios from 'axios'
import { ref, onMounted } from 'vue'
const tag = ref()
const tags = ref([])
onMounted(() => {
tags.value = []
Promise.all([
axios.get('/api/v1/tags')
// ... some more requests here
]).then(([respTags]) => {
tags.value = respTags.data
}).catch($error => {
toast.add({ severity: 'error', detail: $error, life: 3000 });
}).finally(() => {
isLoading.value = false
})
})
</script>
My problem is that respTags
is an object like {tag1: {version: "1.2.3"}, tag2: {version: "1.2.4"}}
and when I pass it to the dropdown, it says [Vue warn]: Invalid prop: type check failed for prop "options". Expected Array, got Object
.
My goal is that the key of the object (tag1
, tag2
...) are used as value and version
is used as the label.
I know that I can do it using a for loop, but is there any chance to prevent implementing a separate loop for doing this?
[Vue warn]: Invalid prop: type check failed for prop "options". Expected Array, got Object
The message is clear. You are passing an object instead of an array. You should pass an array.
const objectFromApiResult = respTags.data // {tag1: {version: "1.2.3"}, tag2: {version: "1.2.4"}}
tags.value = Object.keys(objectFromApiResult).map((key) => ({
value: key,
label: objectFromApiResult[key].version
})) // [{label: "1.2.3", value: "tag1"}, {label: "1.2.4", value: "tag2"}]
With Object.keys()
, I create an array containing the keys of your object. Then, I manipulate each element using .map
, and instead of the string-type key name, I insert an object with two properties, label and value.
Object.keys()
- MDN Docs
Array.property.map()
- MDN Docs
Dropdown - props.options
- PrimeVue Docs (required, type array
)
An array of selectitems to display as the available options.
You can specify the column names of the key and value variables in the object present within the array. The column name for the label can be passed using the props.optionLabel
property, and the corresponding value can be set using the props.optionValue
property.
<Dropdown v-model="tag" :options="tags" optionLabel="name" optionValue="version" />
const objectFromApiResult = respTags.data // {tag1: {version: "1.2.3"}, tag2: {version: "1.2.4"}}
tags.value = Object.keys(objectFromApiResult).map((key) => ({
version: objectFromApiResult[key].version,
name: `Version: ${objectFromApiResult[key].version}, TagKey: ${key}`
})) // [{version: "1.2.3", name: "Version: 1.2.3, TagKey: tag1"}, {version: "1.2.4", name: "Version: 1.2.4, TagKey: tag2"}]
Dropdown - props.optionLabel
- PrimeVue Docs - (optional, type string
, default: label
)
Dropdown - props.optionValue
- PrimeVue Docs - (optional, type string
, default: value
)
So, the label and value can be referenced from a single property as well.
<Dropdown v-model="tag" :options="tags" optionLabel="version" optionValue="version" />
const objectFromApiResult = respTags.data // {tag1: {version: "1.2.3"}, tag2: {version: "1.2.4"}}
tags.value = Object.keys(objectFromApiResult).map((key) => ({
version: objectFromApiResult[key].version,
})) // [{version: "1.2.3"}, {version: "1.2.4"}]
Although in this case, using the Object.values
function is more reasonable than Object.keys
.
<Dropdown v-model="tag" :options="tags" optionLabel="version" optionValue="version" />
const objectFromApiResult = respTags.data // {tag1: {version: "1.2.3"}, tag2: {version: "1.2.4"}}
tags.value = Object.values(objectFromApiResult) // [{version: "1.2.3"}, {version: "1.2.4"}]
Object.values()
- MDN Docs