Dynamic computed property name

Viewed 11046
computed: {

    ...mapGetters(['getElements']),

    element() {
        return this.getElements(this.formId, this.sectionId, this.elementId);
    },

    [this.element.inputName]: { 
    },

}

throws an error: Uncaught TypeError: Cannot read property 'element' of undefined

How do I set the prop name dynamically?

3 Answers

You can add computed properties dynamically, as per this post,

Generating computed properties on the fly.

Since the property name source is nested and (likely) async, you will need a deep watcher to handle changes.

Usage of the property is limited, you cannot use it on an SFC template which is compiled at creation time. When using it in a method, you might need to check it's existence depending on the call sequence.

computed: {
  element() {
    return this.getElements(...);
  },
},
watch: {
  element: {
    handler: function (newValue) {
      if (newValue.inputName) {
        this.addProp(['element', 'inputName'], () => { return 'someValue' })
      }
    },
    deep: true
  }
},
methods: {
  addProp (path, getter) {
    // Get property reference or undefined if not (yet) valid
    const propName = path.reduce((acc, prop) => acc ? acc[prop] : undefined, this)
    if (!propName) { return }

    const computedProp = {
      get() {
        return getter()
      }
    }
    this[propName] = computedProp
  },
}

At the creation of the Vue component options object your this is not the Vue instance of the component (its before the creation), so you dont have the ability to use things like computed porperties or other Vue component properties ( props, data etc ...)

I had the same problem, or want rather I did this...

<script>
export default {
  data: {
    return: {
      init: 0
    }
  },
computed: {
    makeComputed() { 
init++ // call something in data to fire the computed function  
      Object.assign(this, ...this.$store.state.auth.objectwithmanyprops)
      return this.$store.state.auth.objectwithmanyprops 
    }
}
Related