41

I'm using vue@2.1.3 and the vue official webpack template to build an app.

When developing locally, I often see the warning Uncaught TypeError: Cannot read property ... of undefined, but the HTML can be rendered successfully. However, the HTML can't be rendered when it's deployed to Netlify with npm run build command. So I have to treat this warning seriously.

I learned from here that it's because "the data is not complete when the component is rendered, but e.g. loaded from an API." and the solution is to "use v-if to render that part of the template only once the data has been loaded."

There are two questions:

  1. I tried wrap v-if around multiple statements that's generating the warning but personally I think this solution is verbose. Is there a neater approach?
  2. "warnings" in local development turn into "fatal errors" (HTML can't be rendered) in production. How to make them the same in both environments? e.g. both of them issue warnings or errors?
Dave Mackey
  • 4,306
  • 21
  • 78
  • 136
Jerry Zhang
  • 1,251
  • 2
  • 13
  • 15

4 Answers4

74

Just use v-if on a common parent to all the elements in your template relying on that AJAX call, not around each one.

So instead of something like:

<div>
  <h1 v-if="foo.title">{{ foo.title }}</h1>
  <p v-if="foo.description">{{ foo.description }}</p>
</div>

Do

<div>
  <template v-if="foo">
    <h1>{{ foo.title }}</h1>
    <p>{{ foo.description }}</p>
  </template>
</div>
Bill Criswell
  • 32,161
  • 7
  • 75
  • 66
  • 3
    Thank you for your quick reply. This works. While I wonder if this is the only solution since I don't really want to remember to put a `v-if` on top of every component that has AJAX call. But your solution has already removed a large part of my headache. Thanks again. – Jerry Zhang Dec 09 '16 at 02:28
  • 1
    No problem. I'm not sure how much data you're loading but you might be able to load it all up front then when that's ready show the rest of your app. – Bill Criswell Dec 09 '16 at 02:38
9

have you tried to initialize all the data you need? e.g. if you need a b c, you can do:

new Vue({
  data: {
    a: 1,
    b: '',
    c: {}
  },
  created(){
    // send a request to get result, and assign the value to a, b, c here

  }
})

In this way you wont get any xx is undefined error

Sabrina Luo
  • 3,810
  • 4
  • 16
  • 35
8

Guys are right but I can add something. If there is possibility that your root element in the condition can be undefined for some reason, it is good practice to use something like that: v-if='rootElement && rootElement.prop'. It will secure you from getting cannot get property prop of undefined as when rootelement is undefined, it will not go further in checking.

Marek Urbanowicz
  • 12,659
  • 16
  • 62
  • 87
2

2021 vue3

we can use like this

props: {
    form: {
      type: String,
      required: true,
    },
 setup(props, context) {
    console.log(props.form)
rnewed_user
  • 1,386
  • 7
  • 13