In my Vue3 component, I created a feature to showcase data using chips. The input is an Object with keys as indexes and values containing the element to be displayed.
Here is the complete code documentation:
<template>
<div class="row">
<div>a fixed entry during debug</div>
<q-chip v-for="alert in failedAlerts" :key="alert.Id" color="orange">{{ alert.FullTargetName }}</q-chip>
</div>
</template>
<script lang="ts">
import {toRef, Ref, computed, watch} from 'vue'
import log from 'assets/log'
interface Alert {
IsOK: boolean;
FullTargetName: string,
Why: string,
Extra: string,
Id: string,
When: string
}
function alertFactory(): Alert {
return {
Extra: '', FullTargetName: 'dummy alert', Id: '0', IsOK: false, When: '0', Why: 'dummy alert explanation',
}
}
export default {
name: 'Homemonitor',
// the complete props definitiin is temporarily commented out to make sure the problem
// does not come from here
// props: {
// alerts: {
// type: Object,
// default: () => alertFactory(),
// },
// },
props: ['alerts'],
setup(props) {
// TODO: review the global eslint exclusions below
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
let failedAlerts = computed(() => Object.values(toRef(props, 'alerts')).filter((x: Alert) => !x.IsOK))
return {failedAlerts}
},
}
</script>
<style scoped>
</style>
Upon inspecting DevTools → Vue, I noticed that failedAlerts
wasn't the expected neat Array of Alert
, but rather
https://i.sstatic.net/zRNI9m.png
alert
in both props and
setup → failedAlerts → alerts` contains the correct content
https://i.sstatic.net/Al3N6m.png
The issue arises because Object.values()
should have returned an Array of values from the object (filtered).
Based on the provided data, it should look something like this: (IsOK
being true
would filter it out)
// failedAlerts
[
{
"IsOK":true,
"FullTargetName":"bind → Amazon_Fire",
"Why":"",
"Extra":"",
"Id":"8bd3b2c7fe73ea6c0d0aac324baaa354",
"When":"2021-08-19T13:02:33+02:00"
},
(...)
]
What could be causing failedAlerts
to have the current structure?
UPDATE: After carefully examining the types in my code (thanks to @EstusFlask for the help), I believe I have resolved the issues in the <script>
section.
<script lang="ts">
import {computed, Ref, toRef, watch} from 'vue'
interface Alert {
IsOK: boolean;
FullTargetName: string,
Why: string,
Extra: string,
Id: string,
When: string
}
function alertFactory(): Record<string, Alert> {
return {
'dummy index':
{
Extra: '', FullTargetName: 'dummy alert', Id: '0', IsOK: false, When: '0', Why: 'dummy alert explanation',
},
}
}
export default {
name: 'Homemonitor',
props: {
alerts: {
type: Object,
required: true,
// default: () => alertFactory(),
},
},
// props: ['alerts'],
setup(props) {
// TODO: review the global eslint exclusions below
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
let failedAlerts = computed(() => Object.values(props.alerts as Ref<Record<string, Alert>>).filter((x: Alert) => !x.IsOK))
return {failedAlerts}
},
}
</script>