JSPM

  • Created
  • Published
  • Downloads 18914
  • Score
    100M100P100Q148409F
  • License MIT

Async computed properties for Vue

Package Exports

  • vue-async-computed

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (vue-async-computed) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

vue-async-computed

NPM Version Coverage Status Build Status Downloads Dependency Status License

This plugin is now Vue 2.0 compatible!

With this plugin, you can have have computed properties in Vue that are computed asynchronously.

Without using this plugin, you can't do this:

new Vue({
  data: {
    userId: 1
  },
  computed: {
    username () {
      // Using vue-resource
      return Vue.http.get('/get-username-by-id/' + this.userId)
        // This assumes that this endpoint will send us a response
        // that contains something like this:
        // { 
        //   "username": "username-goes-here"
        // }
        .then(response => response.data.username)
    }
  }
}

Or rather, you could, but it wouldn't do what you'd want it to do. But using this plugin, it works just like you'd expect:

new Vue({
  data: {
    userId: 1
  },
  asyncComputed: {
    username () {
      return Vue.http.get('/get-username-by-id/' + this.userId)
        .then(response => response.data.username)
    }
  }
}

This is especially useful with ES7 async functions:

new Vue({
  asyncComputed: {
    async someCalculation () {
      const x = await someAsycFunction()
      const y = await anotherAsyncFunction()
      return x + y
    }
  }
})

Install

npm install --save vue-async-computed

Alternately, you can link it directly from a CDN:

<script src="https://unpkg.com/vue-async-computed"></script>
<!-- 
  That will always point to the latest version of vue-async-computed.
  You probably want to instead pin it to a specific version:
-->
<script src="https://unpkg.com/vue-async-computed@2.1.1"></script>

When used with a module system such as webpack or browserify, you need to explicitly install vue-async-computed via Vue.use():

import Vue from 'vue'
import AsyncComputed from 'vue-async-computed'

Vue.use(AsyncComputed)

You don't need to do this when using global script tags. So long as you include vue-async-computed in a script tag after Vue itself, it will be installed automatically.

Usage example

import AsyncComputed from 'vue-async-computed'

/* Initialize the plugin */
Vue.use(AsyncComputed)

/*
   Then, when you create a Vue instance (or component),
   you can pass an object named "asyncComputed" as well as
   or instead of the standard "computed" option. The functions
   you pass to "asyncComputed" should return promises, and the values
   those promises resolve to are then asynchronously bound to the
   Vue instance as they resolve. Just as with normal computed
   properties, if the data the property depends on changes
   then the property is re-run automatically.
   
   You can almost completely ignore the fact that behind the
   scenes they are asynchronous. The one thing to remember is
   that until a asynchronous property's promise resolves
   for the first time, the value of the computed property is null.
*/

const vm = new Vue({
  data: {
    x: 2,
    y: 3
  },
  asyncComputed: {
    sum () {
      const total = this.x + this.y
      return new Promise(resolve =>
        setTimeout(() => resolve(total), 1000)
      )
    }
  }
})

/*
   Until one second has passed, vm.sum will be null.  After that,
   vm.sum will be 5. If you change vm.x or vm.y, then one
   second later vm.sum will automatically update itself to be
   the sum of the values to which you set vm.x and vm.y the previous second.
*/

Like with regular synchronous computed properties, you can pass an object with a get method instead of a function, but unlike regular computed properties, async computed properties are always getter-only. If the object provided has a set method it will be ignored.

Async computed properties can also have a custom default value, which will be used until the data is loaded for the first time:

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

/*
   Now you can display {{blogPostContent}} in your template, which
   will show a loading message until the blog post's content arrives
   from the server.
*/

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.

If you want to use a custom logging function, the plugin takes an errorHandler option, which should be the function you want called with the error information.

For example:

Vue.use(AsyncComputed, {
  errorHandler (msg) {
    console.log('Hey, an error!')
    console.log('---')
    console.log(msg)
  }
)

You can pass false in order to silently ignore rejected promises.

License

MIT © Benjamin Fox