mmachenry
mmachenry

Reputation: 1962

Why doesn't a VueJS prop reactively update when it's an argument to a method?

I have this component with two text-fields with two expressions that should evaluate to the same thing.

<template>
  <div>
    {{ value.flange?value.circle.diameter:413 }}
    {{ get(value, 'circle.diameter') }}
  </div>
</template>

<script>
import _ from "lodash/fp"

export default {
  name: "MyComponent",
  props: {
    value: {
      type: Object,
      default: () => ({}),
    },
  },
  methods: {
    get (obj, path) {
      return _.get(obj, path)
    },
  },
}
</script>

This is my attempt to guard my page from crashing on property look ups for the brief moment when this.value is undefined. I prefer to use lodash/fp's _.get function since it's a lot more readable and much less tedious for deeper nested objects.

However, when I load this page, I see brief momentary blip of 413 and nothing, which is expected. Since 413 is my placeholder value for the first expression and the second should be undefined. Then when value gets an update, the 413 quickly changes to value.circle.diameter, as it should, but the one wrapped in the get never updates.

Why is a method call blocking propagation and how should I in general guard against my deeply nested objects from crashing on property access when value is undefined?

Note: I don't want to block render of the page when the object is null with, for example, a v-if="value" on my div. This is because I want to be able to edit the value if it's {} and construct that structure as the user edits it.

Upvotes: 0

Views: 49

Answers (1)

Gabor Angyal
Gabor Angyal

Reputation: 2255

This is because properties are reactive and function calls are not. However, you can achieve this with computed properties:

<template>
  <div>
    {{ value.flange?value.circle.diameter:413 }}
    {{ diameter }}
  </div>
</template>

<script>
import _ from "lodash/fp"

export default {
  name: "MyComponent",
  props: {
    value: {
      type: Object,
      default: () => ({}),
    },
  },
  computed: {
    diameter: function () {
      return _.get(this.value, 'circle.diameter');
    }
  }
}
</script>

Upvotes: 2

Related Questions