Skip to content

Commit

Permalink
Allow functions to generate defualt values for async computed properties
Browse files Browse the repository at this point in the history
  • Loading branch information
foxbenjaminfox committed Jan 20, 2017
1 parent 5c6c4f5 commit f3511e0
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Changelog

- [v3.0.0](#v300)
- [v2.1.1](#v211)
- [v2.1.0](#v210)
- [v2.0.0](#v200)
Expand All @@ -12,6 +13,10 @@

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

### v3.0.0
* Pass the raw error to the error handler when passed the `useRawError` option.
* Allow default values to be given as functions.

### v2.1.1
* Automatic installation when used in a script tag.

Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,28 @@ new Vue({
*/
````

You can instead define the default value as a function, in order to depend on
props or on data:

````js
new Vue({
data: {
postId: 1
},
asyncComputed: {
blogPostContent: {
get () {
return Vue.http.get('/post/' + this.postId)
.then(response => response.data.postContent)
},
default () {
return 'Loading post ' + this.postId
}
}
}
}
````

## Options

By default, in case of a rejected promise in an async computed property, vue-async-computed will take care of logging the error for you.
Expand Down
22 changes: 16 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@ const AsyncComputed = {
Vue.mixin({
beforeCreate () {
const optionData = this.$options.data
const newData = {}

if (!this.$options.computed) this.$options.computed = {}

Object.keys(this.$options.asyncComputed || {}).forEach(key => {
const fn = this.$options.asyncComputed[key]
const get = typeof fn === 'function' ? fn : fn.get,
def = typeof fn.default === 'undefined' ? null : fn.default
const fn = this.$options.asyncComputed[key],
get = typeof fn === 'function' ? fn : fn.get

this.$options.computed[prefix + key] = get
newData[key] = def
})

this.$options.data = function vueAsyncComputedInjectedDataFn () {
Expand All @@ -30,11 +27,24 @@ const AsyncComputed = {
? optionData.call(this)
: optionData
) || {}
Object.keys(newData).forEach(key => { data[key] = newData[key] })
Object.keys(this.$options.asyncComputed || {}).forEach(key => {
data[key] = null
})
return data
}
},
created () {
Object.keys(this.$options.asyncComputed || {}).forEach(key => {
const fn = this.$options.asyncComputed[key],
def = typeof fn.default === 'undefined' ? null : fn.default

if (typeof def === 'function') {
this[key] = def.call(this)
} else {
this[key] = def
}
})

Object.keys(this.$options.asyncComputed || {}).forEach(key => {
let promiseId = 0
this.$watch(prefix + key, newPromise => {
Expand Down
29 changes: 29 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,32 @@ test("Async computed values can have defaults", t => {
t.equal(vm.z, true, 'z resolves to true')
})
})

test("Default values can be functions", t => {
t.plan(4)
const vm = new Vue({
data: {
x: 1
},
asyncComputed: {
y: {
default () { return 2 },
get () {
return Promise.resolve(3)
}
},
z: {
default () { return this.x },
get () {
return Promise.resolve(4)
}
}
}
})
t.equal(vm.y, 2)
t.equal(vm.z, 1)
Vue.nextTick(() => {
t.equal(vm.y, 3)
t.equal(vm.z, 4)
})
})

0 comments on commit f3511e0

Please sign in to comment.