Home > Software design >  v-model nested value from schema is always undefined
v-model nested value from schema is always undefined

Time:09-18

I am doing a component in vue.js 2.6

<v-sheet >
    <v-form>
      <v-row>
        <v-col cols="12" sm="10" md="3" lg="3" xl="3">
          <v-card >
            <h4 >Hourly</h4>
            <v-divider />
            <v-row justify="center" >
              <v-col cols="10">
                <v-text-field type="text" label="Click" outlined dense v-model="prop1.prop2.hourly.click.value"/>
              </v-col>              
            </v-row>
          </v-card>
        </v-col>   
      </v-row>
    </v-form>
  </v-sheet>

and I am obtaining prop1 value from schema in backend

<script lang="ts">
import {  Prop1} from "@pro1-schema";
import {PropType} from "vue";
export default {
  name: "component1-name",
  props: {
    prop1: { type: Object as PropType<Prop1 | null>, default:()=> ({}) },

  },
  data() {

  },
};
</script>

intellisense is accurate, always suggesting me correctly the prop that is comming next, wanted to set the variable here

<v-text-field type="text" label="Click" outlined dense v-model="prop1.prop2.hourly.click.value"/>

in this line but prop1.prop2 is always undefined.

Prop1
export interface Prop1 {
    
    prop2?: PropQuotas;
}
PropQuotas
export interface PropQuotas {
   
    hourly?: PropQuota;
    
}
PropQuota
export interface PropQuota {    
    click?: PropQuotaValue;    
}
PropQuotaValue
export interface PropQuotaValue{    
    value?: number;    
}

How to work around this and get rid of this error?

[Vue warn]: Error in render: "TypeError: _vm.prop1.prop2 is undefined"

CodePudding user response:

prop1: { type: Object as PropType<Prop1 | null>, default:()=> ({}) },

Here you're setting the default value of prop1 as an empty object. It makes sense then that prop1.prop2 is undefined, because by default prop2 doesn't exist on prop1. Even if some very short time after component creation do you pass down an actual value to prop1 from a parent component, you still need to make sure that your template code can handle prop1 as it is before it has any value. I have two possible suggestions:

  1. Provide default properties when defining prop1, something similar to:
prop1: { type: Object as PropType<Prop1 | null>, 
default:()=> ({
  prop2: {
    hourly: {
      click: {
        value: null
      }
    }
  }}) 
},
  1. Use v-if to not render the text field until the prop has a value.:
<v-text-field v-if="validProp" type="text" label="Click" outlined dense v-model="prop1.prop2.hourly.click.value"/>
computed: {
  validProp() {
    return this.prop1?.prop2?.hourly?.click?.value !== undefined;
  },
},

You could optionally abstract this into a generic isLoading boolean prop set by the parent based on the current fetch/loading status of prop1

  • Related