foxbenjaminfox/vue-async-computed

[feature request] Use data properties as defaults

wujekbogdan opened this issue · 8 comments

I know that we can define defaults using the following syntax:

{
  asyncComputed: {
    item: {
      get() {
        // Do something asynchronous
      },
      default: [], // default value
    },
  },
};

But it would be great if we could use data to define defaults as follows:

{
  data: () => ({
    item: [], // default value
  }),
  asyncComputed: {
    item() {
      // Do something asynchronous
    },
  },
};

I'm not quite sure how it is an improvement to specify the default in data. What makes you prefer this proposed method for defining defaults for your async computed properties?

What makes you prefer this proposed method for defining defaults for your async computed properties?

There are 2 reasons:

  1. It's more Vue-way.
  2. All the defaults (async and standard Vue properties) would be grouped together. That would make the code easier to read.

vue-apollo does the same thing, data() serves as the placeholder until results from the server are in.

vue-apollo does the same thing, data() serves as the placeholder until results from the server are in.

Same in vuefire. That's why I said it's kind of a vue-way.

I see. I suppose it is worth having some consistency with vue-apollo and vuefire, and if they do it this way, it's probably worth having the ability to do the same thing. Personally, I like to think of asyncComputed properties as being more like the component's computed properties than like data, so it makes more sense to me to have the default of an async computed property to be where that property is defined, not in data. But others might see things differently, and as other similar libraries support defining defaults in data, it makes sense to add the ability to be consistent there.

I'll add this feature, or if one of you would like to send a PR you could.

This is not really the vue way to do it.

Vue defines properties on the instance as sort of aliases of either pops, data or computed. So the vue way is what asyncComputed is doing currently: Add new properties to the instance (and not transform data properties). Currently, no conflict checking is done between async computed properties and data properties (but that should be done).

AsyncComputed is an enhancement (convenience implementation) of Vue's computed. These are not defined as component data, but defined when they're created. It follows that AsyncComputed should behave the same way. If one needs default values, use AsyncComputed's own default:

Computed

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

AsyncComputed

  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
       },
       // The computed proporty `blogPostContent` will have 
       // the value 'Loading...' until the first time the promise
       // returned from the `get` function resolves.
       default: 'Loading...'
    }
  }
amw commented

Current behavior is also in line with Vue's own props. Properties also declare default values by passing a description object and not using data.