Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/v-if-null-check-order.md
1---2title: Check for Null/Undefined Before Accessing Properties in v-if3impact: MEDIUM4impactDescription: Accessing properties on null/undefined causes runtime errors and crashes5type: capability6tags: [vue3, conditional-rendering, v-if, null-check, defensive-programming]7---89# Check for Null/Undefined Before Accessing Properties in v-if1011**Impact: MEDIUM** - Accessing properties on null or undefined objects in `v-if` conditions causes "Cannot read property of undefined" runtime errors. This commonly occurs when data is loaded asynchronously or when optional object properties are accessed without null checks.1213## Task Checklist1415- [ ] Always check that an object exists before accessing its properties16- [ ] Use optional chaining (?.) in Vue 3 templates for cleaner null checks17- [ ] Consider using computed properties for complex conditional logic18- [ ] Handle loading states explicitly rather than relying on undefined checks1920**Incorrect:**21```html22<!-- WRONG: Accessing property before checking object exists -->23<template>24<div v-if="user.isAdmin">25Admin Panel26</div>27<!-- Error if user is null/undefined: Cannot read property 'isAdmin' of undefined -->28</template>29```3031```html32<!-- WRONG: Nested property access without checks -->33<template>34<div v-if="order.customer.address.city === 'NYC'">35Local delivery available36</div>37<!-- Error if any level is undefined -->38</template>39```4041```html42<!-- WRONG: Array access without existence check -->43<template>44<div v-if="items[0].name === 'Featured'">45{{ items[0].description }}46</div>47<!-- Error if items is empty array -->48</template>49```5051**Correct:**52```html53<!-- CORRECT: Check object exists first with && -->54<template>55<div v-if="user && user.isAdmin">56Admin Panel57</div>58</template>59```6061```html62<!-- CORRECT: Optional chaining (Vue 3) -->63<template>64<div v-if="user?.isAdmin">65Admin Panel66</div>67</template>68```6970```html71<!-- CORRECT: Optional chaining for nested properties -->72<template>73<div v-if="order?.customer?.address?.city === 'NYC'">74Local delivery available75</div>76</template>77```7879```html80<!-- CORRECT: Array length check before access -->81<template>82<div v-if="items.length > 0 && items[0].name === 'Featured'">83{{ items[0].description }}84</div>8586<!-- Or with optional chaining -->87<div v-if="items?.[0]?.name === 'Featured'">88{{ items[0].description }}89</div>90</template>91```9293```html94<!-- CORRECT: Explicit loading state handling -->95<template>96<div v-if="isLoading">Loading...</div>97<div v-else-if="error">Error: {{ error.message }}</div>98<div v-else-if="user">99<h1>Welcome, {{ user.name }}</h1>100<div v-if="user.isAdmin">Admin Panel</div>101</div>102<div v-else>No user data</div>103</template>104```105106## Using Computed Properties for Complex Checks107108```javascript109// CORRECT: Move complex checks to computed properties110<script setup>111import { computed } from 'vue'112113const props = defineProps(['user', 'permissions'])114115const canAccessAdmin = computed(() => {116return props.user?.isAdmin &&117props.permissions?.includes('admin_panel') &&118!props.user?.isDisabled119})120121const userDisplayName = computed(() => {122return props.user?.profile?.displayName ||123props.user?.name ||124'Anonymous'125})126</script>127128<template>129<div v-if="canAccessAdmin">130Admin Panel131</div>132<span>{{ userDisplayName }}</span>133</template>134```135136## Common Async Data Pattern137138```javascript139// CORRECT: Handle async data loading properly140<script setup>141import { ref, onMounted } from 'vue'142143const user = ref(null)144const isLoading = ref(true)145const error = ref(null)146147onMounted(async () => {148try {149user.value = await fetchUser()150} catch (e) {151error.value = e152} finally {153isLoading.value = false154}155})156</script>157158<template>159<div v-if="isLoading">Loading user...</div>160<div v-else-if="error">Failed to load user</div>161<div v-else-if="user">162<!-- Safe to access user properties here -->163<h1>{{ user.name }}</h1>164<p v-if="user.bio">{{ user.bio }}</p>165</div>166</template>167```168169## Reference170- [Vue.js Conditional Rendering](https://vuejs.org/guide/essentials/conditional.html)171- [MDN - Optional Chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining)172