5

I have the following Vue component:

Vue.component('result', {
  props: ['stuff'],
  data: () => ({}),
  template: "<img :src='tag' class='result'></img>",
  computed: {
    tag: function tag() {
      return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
    }
  }
});

When the component is created, an error is thrown:

TypeError: Cannot read property 'toLowerCase' of undefined
  at VueComponent.tag

However, when I remove the call to toLowerCase(), the method executes properly, generating a string with the expected type. I could work around this by changing my filenames to have capital letters, but I would rather understand why Vue is behaving this way. Why would a property be undefined only when methods are called on it?

Update: after some troubleshooting, I found that this.stuff.type is undefined the first time tag() is computed. Calling toLowerCase() just forces an error on an otherwise silent bug. Is there a reason the props aren't defined when computed functions are called for the first time? Should I be writing my component differently?

0

2 Answers 2

4

The stuff prop is undefined when the result component is created.

There are two options to fix this problem:

Either use the v-if directive in the parent component's template to make sure stuff has a value when the result component is created:

<template>
  <result v-if="stuff" :stuff="stuff" />
</template>

Or handle the stuff prop being undefined in the result component.

Vue.component('result', {
  props: {
    // Object with a default value
    stuff: {
      type: Object,
      // Object or array defaults must be returned from
      // a factory function
      default: () => ({ type: 'someType'})
    },
  },

  data: () => ({}),

  template: "<img :src='tag' class='result' >",

  computed: {
    tag: function tag() {
      return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
    }
  }
})

Note: The img element is a void element, it does not require an end tag.

Sign up to request clarification or add additional context in comments.

Comments

0

Props are by default null but you can give them a default value to overcome this problem.

Example :

Vue.component('result', {
  props: {
    stuff: {
      type: Object,
      default: {
        type: ''
      }
    }
  },
  data: () => ({}),
  template: "<img :src='tag' class='result'></img>",
  computed: {
    tag: function tag() {
      return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
    }
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.