foxbenjaminfox/vue-async-computed

Recalculation of async computed has incorrect context when using object form

half2me opened this issue · 3 comments

When an async computed property is created in the following way:

asyncComputed: {
  myProp: {
    get() {},
  },
}

Calling this.$asyncComputed.myProp.update() will not set the proper context for the property to use this. Infact, this will be undefined. If asyncComputed is a function instead of an object, it works.

Here is a simple example showing the problem. When the property is calculated automatically everything works as expected, but when manually triggering an update(), this is not defined.

<template>
  <div class="hello">
    <h1>{{ test }}</h1>
    <button @click="recalc">Recalculate</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  asyncComputed: {
    test: {
      get() {
        return new Promise((resolve, reject) => {
          setTimeout(() => resolve(this.msg), 1000);
        });
      },
      default: "calculating"
    }
  },
  data() {
    return {
      msg: "Welcome to Your Vue.js App"
    };
  },
  methods: {
    recalc() {
      this.$asyncComputed.test.update();
    }
  }
};
</script>

You can see this example in action here:
Edit Vue Template

Thanks for finding this, I can look into it in ~ 2 weeks.

The workaround seems to be fine for this.

The clean solution would be to hide the editable $asyncComputed property completely and only expose the computed property. The same way all other properties should then only be exposed as computed properties, which avoids accidental assignments to those properties and solves the current problem that using asyncComputed hides the "data should be a function" warning

I was planning to fix this last week, but due to other issues I need to postpone the fixes to around January 20.

@michaelzangl looking forward to the fix, it would be very helpful for me.