Git Product home page Git Product logo

vue-async-computed's People

Contributors

alex-dunn avatar bumfo avatar cdrini avatar djmattyg007 avatar eladfrizi avatar firefligher avatar flamenco avatar foxbenjaminfox avatar jin5354 avatar johannes-z avatar michaelzangl avatar mtorromeo avatar nwtgck avatar perymimon avatar sharkykh avatar shrpne avatar skoschnicke avatar thooyork avatar tjallingt avatar wmcmurray avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-async-computed's Issues

upload as script tag

Hello, I'm new in Vue js and module loading...

i want to to upload the plugin using something like

<script src="./vue.async.js"></script>

How can I achieve that?

thanks

Default Values

This plugin has been a life saver for me and my team. Thank You!

One issue we run into, though, is that we get Vue warnings from our templates when the asyncComputed property has not yet resolved. Do you think there is any way to set a default value that is returned while the promise(s) has not resolved?

Pass raw err to errorHandler callback

Hello,

It would be nice to use raw err in errorHandler callback:

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

Can't make it work with watcher for some reason

Hi, guys!
Great project you have here. I have one issue thought. For some very odd reason my watcher on async computed property does not initialize recalc. Example:

    export default
    {
        data: function()
        {
            return {
                refreshCount: 0,
            };
        },

        asyncComputed: {
            countries: {
                get()
                {
                    return CountryCollection
                        .find({})
                        .sort([ "Name" ]);
                },
                watch()
                {
                    this.refreshCount;
                }
            }
        },

        methods: {
            refreshCountryList()
            {
                this.refreshCount++;
            },
        }
    }

First time data is being fetched as expected but if I call this.refreshCountryList() for some reason watcher does not pickup anything even when property is updated to +1. Maybe I am not doing something correctly? Although I I did everything according to README...

clear value before updating

It would be nice (also with a setting-parameter) to clear the value while updating.
like:

<div v-if="!data">{{ data }}</div>
<spinner v-else/>
export default {
    asyncComputed: {
        data () {
            return this.http.get('...', {
                params: {
                    property: this.someProperty
                }
            })
        }
    }
}

so every time, someProperty my asyncComputed-property data gets evaluated, but the spinner component is shown only the first time.
there should be a possibility to say, set data to default value every time before the promise gets evaluated

Is it possible to set the default value of an asyncComputed property?

I am using this plugin to render a dynamic list which updates when other properties in the component change.

In my view I have a simple check to see if the computer value has a length of zero to display a "No results message":

<tr v-if="list.length < 1" class="no-results">
    <td colspan="10" class="has-text-centered">No results</td>
</tr>

However, by default, when the component initialises the value for list is null which throws an error saying that the property length of undefinedis not found. Is there any way to set the default value of a computed property? I'd like to avoid filling my view with multiple checks for if the property is null or has a length less than one.

I noticed it's possible to set the global default value, but I don't think this approach will work for me as in other components I am expecting the value to be null.

Can't import using commonjs

Add support for loading with CommonJS syntax too AsyncComputed = require('vue-async-computed').

In the meanwhile a workaround is to use AsyncComputed = require('vue-async-computed').default

feature request - debounce asyncComputed

It would be nice to be able to define a computed function which waits for 0 or more milliseconds before issuing the compute request, and provides various options for what happens if subsequent requests arrive during that delay.

I'm using asyncComputed currently with fetch, but I want to throttle the number of fetch requests being made, and show a "working..." temporary output or something.

Thanks!

Issue with watch in asyncComputed.

I'm trying to use the next code:

export default {
    asyncComputed: {
        myAwesomeF: {
            get() { },
            watch:  ['fn']
        },
        fn: {
            get() { }
        },
    }
}

and after build it provide the next error trace:

vendor.js?186b24eb556f851a18b5:2185 [Vue warn]: Error in getter for watcher "_async_computed$myAwesomeFn": "TypeError: fn.watch.call is not a function"

found in

---> <Root> at src\toolbar\root.vue
       <Root>
warn @ vendor.js?186b24eb556f851a18b5:2185
logError @ vendor.js?186b24eb556f851a18b5:3329
globalHandleError @ vendor.js?186b24eb556f851a18b5:3324
handleError @ vendor.js?186b24eb556f851a18b5:3313
get @ vendor.js?186b24eb556f851a18b5:4737
Watcher @ vendor.js?186b24eb556f851a18b5:4723
Vue.$watch @ vendor.js?186b24eb556f851a18b5:5203
created @ vendor.js?186b24eb556f851a18b5:66729
callHook @ vendor.js?186b24eb556f851a18b5:4513
Vue._init @ vendor.js?186b24eb556f851a18b5:6222
VueComponent @ vendor.js?186b24eb556f851a18b5:6390
createComponentInstanceForVnode @ vendor.js?186b24eb556f851a18b5:5902
init @ vendor.js?186b24eb556f851a18b5:5723
createComponent @ vendor.js?186b24eb556f851a18b5:7200
createElm @ vendor.js?186b24eb556f851a18b5:7147
patch @ vendor.js?186b24eb556f851a18b5:7722
Vue._update @ vendor.js?186b24eb556f851a18b5:4252
updateComponent @ vendor.js?186b24eb556f851a18b5:4380
get @ vendor.js?186b24eb556f851a18b5:4734
Watcher @ vendor.js?186b24eb556f851a18b5:4723
mountComponent @ vendor.js?186b24eb556f851a18b5:4387
Vue.$mount @ vendor.js?186b24eb556f851a18b5:10132
Vue.$mount @ vendor.js?186b24eb556f851a18b5:12531
Vue._init @ vendor.js?186b24eb556f851a18b5:6232
Vue @ vendor.js?186b24eb556f851a18b5:6321
575 @ toolbar.js?186b24eb556f851a18b5:2117
__webpack_require__ @ manifest.js?186b24eb556f851a18b5:55
webpackJsonpCallback @ manifest.js?186b24eb556f851a18b5:26
(anonymous) @ toolbar.js?186b24eb556f851a18b5:2
vendor.js?186b24eb556f851a18b5:3333 TypeError: fn.watch.call is not a function
    at VueComponent.getter (vendor.js?186b24eb556f851a18b5:66757)
    at Watcher.get (vendor.js?186b24eb556f851a18b5:4734)
    at Watcher.evaluate (vendor.js?186b24eb556f851a18b5:4841)
    at VueComponent.computedGetter [as _async_computed$myAwesomeFunction] (vendor.js?186b24eb556f851a18b5:5099)
    at VueComponent.<anonymous> (vendor.js?186b24eb556f851a18b5:2071)
    at Watcher.get (vendor.js?186b24eb556f851a18b5:4734)
    at new Watcher (vendor.js?186b24eb556f851a18b5:4723)
    at VueComponent.Vue.$watch (vendor.js?186b24eb556f851a18b5:5203)
    at VueComponent.created (vendor.js?186b24eb556f851a18b5:66729)
    at callHook (vendor.js?186b24eb556f851a18b5:4513)

What am I doing wrong?

Typescript

Any plans to add Typescript support?

Thanks.

this.$asyncComputed.name.update() doesn't allow to access Vue this.

I'm using async computed property like this:

asyncComputed:
        {
            perms:
            {
                lazy: true,
                async get()
                {
                    return (await DelegationsService.getPermissions(this.$route.params.delegationId)).data;
                },
                default:
                {
                    accept: false,
                    edit: false,
                    settlement: false,
                    isOwner: false
                }
            }
        }

It works fine, but when I'm using function this.$asyncComputed.perms.update() inside method, I have got an error called that I have no access to this entity,

Endless loop on navigation back to page with async-computed

I have a computed prop that depends on getting something from firestore, so vue-async-computed seemed like a perfect way to get this into my component. But, I've hit a snag I've not seen before when navigating back to a page that previously had successfully loaded the async value.

My app has 2 routes (/ and /<projectId), and when on a 'project' page, the user can navigate back to the 'home' page which lists all projects.

On the home page, I have this template and computed:

<template>
  <q-page padding>
    <div class="q-headline">Projects:</div>
    <q-list link >
      <q-item v-for="(project, projectId) in asyncAllProjects" :key="projectId"
        @click.native="$router.push(`/${projectId}`)"
      >
        {{project.data().name}}
      </q-item>
    </q-list>
  </q-page>
</template>
.
.
.
    asyncComputed: {
      asyncAllProjects: {
        lazy: true,  // Don't get until binding is done
        async get () {
          console.log('Index: Calling asyc allProjects()...')
          const ap = await this.allProjects()
          console.group('Index: All Projects:', ap)
          _.forEach(ap, (doc, key) => { console.log(key, ':', doc.data()) })
          console.groupEnd()
          return ap
        }
      }
    },

The getter for that calls firebase. Note I've hard coded it to fetch a single project to help with testing:

export const allProjects = () => getters => {  // Must be a function, or it's called early to evaluate
  console.log('→SG Getting allProjects...')

  const docId = 'DalEtsuauL46a9bpSKRH'
  return firebase.firestore().collection('projects').doc(docId).get().then(snapshot => {
    console.log('→SG snapshot:', snapshot)
    return {[docId]: snapshot}
  })
}

On first page load, all works fine, and the projects are listed. I can then click on one and navigate to the project page. But when I navigate back to the home page, the console fills with endless log info from the above, repeatedly calling the getter until it runs out of energy and crashes. At the very start of that endless logging output, I can see that the getter is called twice for some reason:

13:07:38.909 Index.vue?b484:25 Index: Calling asyc allProjects()...
13:07:38.909 getters.js?2e7d:19 →SG Getting allProjects...
13:07:38.912 Index.vue?b484:25 Index: Calling asyc allProjects()...
13:07:38.913 getters.js?2e7d:19 →SG Getting allProjects...

and after that the rest of the logs show endless calls / returns. One thing I did notice via Vue devtools is that on first load, the component has these properties:

image

but on returning to that page it looks like this:

image

I can't tell if that's a symptom or pointing towards a cause. Any ideas which the asyn-computed would be triggered multiple times?

default as function

Hello,

It would be nice to use function for getting default value:

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

$asnyComputed is undefined in computed property when watcher is called first

@foxbenjaminfox

AsyncComputed properties are undefined when being used in a computed property, at least in this edge case that I implemented. I made a sandbox repro: https://codesandbox.io/s/m34kn80m9j

After the latest changes, it's still initially undefined, at least when using watchers. Because of this I can't make computed properties depend on the asyncComputed state, e.g. updating.

Here is the code (unimportant stuff was truncated):

App.vue

<template>
  <div id="app">
    Parent: {{ childProp }}
    <ChildComponent ref="child" @update:someProp="childProp = $event;" />
  </div>
</template>

<script>
import ChildComponent from "./Child.vue";
export default {
  components: { ChildComponent },
  data() {
    return {
      childProp: {}
    };
  }
};
</script>

Child.vue

<template>
  <div>
    Child: {{ someProp }} {{ $asyncComputed.posts.updating }}
    <div v-for="(post, index) in posts" :key="index">{{ post }}</div>
  </div>
</template>

<script>
export default {
  watch: {
    someProp: {
      deep: true,
      immediate: true,
      handler(newVal) {
        this.$emit("update:someProp", newVal);
      }
    }
  },
  computed: {
    someProp() {
      console.log(this.$asyncComputed.posts);
      return {
        prop: "value",
        error: this.$asyncComputed.posts.error
      };
    }
  },
  asyncComputed: {
    posts: {
      lazy: true,
      default: () => [],
      async get() {
        return [1, 2];
      }
    }
  }
};
</script>

Recalculation of async computed has incorrect context when using object form

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

[BUG] 3.5.1 need to remove the `module` attribute immediately, it breaks webpack build

Is module a standard property, @mtorromeo? because so far I see its not but only for rollbar. https://stackoverflow.com/questions/42708484/what-is-the-module-package-json-field-for
Also, this is breaking IE11 support because its importing esm version that does not compile function properly. In module, its using es6 formating (i.e. in compiled js, we have get() instead of correct way of function get())
Please remove this config from the package.json if possible. thank you.

ref line: 9e2d046#diff-b9cfc7f2cdf78a7f4b91a753d10865a2R6

Infinite dependency chains

Thanks for the great library! I'm trying to debug an issue where I end up with 2 async computed properties cyclically triggering each other. As far as I can see it should be only one way. I just wanted to check that it is okay to have one async property depend on another?

The two properties I have are "files" and "currentDir". I expect "files" to depend on "currentDir", but not the other way around. Am I doing something wrong here? The full file is here (context is an object from an external library which returns Promise like objects with "thenApply" methods.

`
currentDir: function() {
var context = this.getContext();
if (context == null)
return Promise.resolve(null);
var x = this.forceUpdate;
var path = this.getPath();
return new Promise(function(resolve, reject) {
context.getByPath(path).thenApply(function(file){
resolve(file.get())
});
});
},

files: function() {
        var current = this.currentDir;
    if (current == null)
	return Promise.resolve([]);
    var that = this;
    return new Promise(function(resolve, reject) {
	current.getChildren(that.getContext()).thenApply(function(children){
	    var arr = children.toArray();
	    that.showSpinner = false;
	    resolve(arr.filter(function(f){
		return !f.getFileProperties().isHidden;
	    }));
	});
    });
    },`

Cannot configure default value when recalculating

I found in README that

... have a custom default value, which will be used until the data is loaded for the first time

But is there a way to configure the default value when recalculating? Currently, it simply keeps the old value until new Promise is done.

Uglify issue with async-computed?

When I try to build my Vue / Quasar app, I get this error during the build process:

ERROR in js/vendor.js from UglifyJs
Unexpected token: punc (() [js/vendor.js:62695,8]

That line is the get () definition in this function:

function makeLazyComputed (key) {
  return {
    get () {
      this[lazyActivePrefix + key] = true;
      return this[lazyDataPrefix + key]
    },
    set (value) {
      this[lazyDataPrefix + key] = value;
    }
  }
}

which I'm guessing is coming from the vue-async-computed module. Any idea why Uglify would object here? You'd mentioned before about Babel settings - perhaps something still isn't quite right?

Call errorCaptured on Promise rejection

When throwing an Error inside the get () method of the asyncComputed, the component's registered errorCaptured handler is not being called. Can/Should this be added?

  errorCaptured: (err, vm, info) => {
    console.log(arguments)
  },
  asyncComputed: {
    posts: {
      lazy: true,
      default: () => [],
      async get () {
        throw new Error('error')
      }
    }
  }

Plugin does not handle watching of data that is updated asynchronously in a methods: function with a Promise inside

I'm not sure if this was intentional out-of-scope, or I am using the plugin incorrectly, but let's say you have some component like this:

data: {
  friends: [],
  selectedIndex: 0
},
methods: {
  load: function() {
    return fetch('someurlhere').catch(...).then(res => {
      this.friends = res.data.friends // this is being set async, and the value is correct
    })
  }
},
created: {
  this.load()
},
asyncComputed: {
  selectedFriend() {
    return new Promise(resolve => resolve(this.friends[this.selectedIndex])
  }
}

In this case, the selectedFriend property is not being properly updated when this.friends is updated in the Promise. Yes, this.friends has the correct data, it's just not triggering a recompute when it's set in load().

FWIW, I can make this work properly by using multiple watch: methods on this.friends and this.selectedIndex, but I was hoping for a cleaner solution.

Compatibility with Vue.js 2.0?

After simply installing the plugin with Vue.use(), it throws an error: Uncaught TypeError: this._initComputed is not a function. I'm using Vue.js 2.0 RC-4, so I assume that's causing the issue. Is adding compatibility for 2.0 on the horizon, or is the issued caused by something else?

Thanks--love the plugin!

vue-async-computed doesn't work in IE

I cannot use vue-async-computed in IE11 using it like this: import AsyncComputed from 'vue-async-computed'. I get the follow Error:

SCRIPT1028: Expected identifier, string or number
chunk-vendors.js (7,10068)

This is the file/line throwing the error:

function makeLazyComputed (key) {
  return {
    get () { // <----------------------------------------
      this[lazyActivePrefix + key] = true;
      return this[lazyDataPrefix + key]
    },
    set (value) {
      this[lazyDataPrefix + key] = value;
    }
  }
}

Update pending property

I currently use this plugin to get resources from the server. I want to display a loading indicator while content is refreshing / updating.

To do this, I'd like to have a property that indicates if a asyncComputed property is being recomputed. Something like:

asyncComputed {
  someData: ...
}
...

this.someData // the computed value
this.someDataIsUpdating // implicit property, true while the computed value is updating

What do you think of this concept? Is it good to have those implicit properties or do you have a better idea? Should I implement it and create a PR?

On Promise error from async computed method, call default()?

Hello! 👍

I think the current behaviour is just render default on start and only reacts with on resolve from the promise but never from the reject of the Promise.

Example given this code:

asyncComputed: {
    menuDynamic: {
      lazy: true,
      get() {
        return () => {
          return import(`./menus/${this.$user.role}.js`).catch(() => {
            return import('./menus/default.js');
          });
        };
      }
    }
  },

I would love using default instead of catch and return default when the first import is failed.

Kind regards,
omar

Possibility of passing a property (acting as a method)

Would it be possible to pass an argument? I can "hack" it on a computed property like below, but asyncComputed properties expect a return that is a promise.

asyncComputed: {
  totals() {
    return {
      inDay(date) {
        return date;
      }
    }
  }
}

I think computed method shouldn't have side effect

Thanks for all of your work, but I think making computed method async is anti vue's design. In my opinion, I think computed method shouldn't change any state or make api call. If you must, I think you'd better use 'watch' instead.

[proposal] Allow watch to bail out of updating

It would allow for a lot of flexibility if watch could return false to bail out of rerunning the getter like so:

new Vue({
  data: {
    postId: 1,
    pageType: 'list',
  },
  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
      },
      watch () {
        return this.pageType !== 'index';
      }
    }
  }
}

This would watch pageType and thus rerun the getter every time the pageType changed but only rerun blogPostContent.get whenever watch is not returning false (meaning current behaviour is preserved as long as nothing is returned).

Potentially in a more breaking update you could even choose to rename watch to shouldUpdate and force it to return either true or false but that'd be a pretty big breaking change and its not necessairy to get a simpler version of this working.

I can submit a pull request for this if you'd be willing to consider merging this @foxbenjaminfox 😄

server-side rendering

Looks like it does not support server-side rendering, Any plans about adding server-side rendering as a new feature in the short term ?

[feature request] Use data properties as defaults

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
    },
  },
};

[3.5.0] Bug when no `data` or `asyncComputed` properties are provided

A bug introduced in version 3.5.0 (most recent) breaks components that do not contain a data property and/or an asyncComputed property.

Meaning, if I have a component definition containing something like:

<template>
    <span>{{ realQuality }}</span>
</template>

<script>
export default {
    name: 'quality-pill',
    props: {
        quality: {
            type: Number,
            required: true,
            validator: value => (value >>> 0) >= 0 // Unsigned int
        }
    },
    computed: {
        realQuality() {
            return this.quality / 100;
        }
    }
};
</script>

It throws these errors:
1.

[Vue warn]: data functions should return an object:
https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

found in

---> <QualityPill> at src/components/helpers/quality-pill.vue
       <Root>
vue.esm.js:3514 Uncaught TypeError: Cannot use 'in' operator to search for 'auth' in undefined
    at initComputed (vue.esm.js:3514)

image


Adding either an empty (at the very least) data property, or an asyncComputed property with at least one async computed property, seems to fix the issue:

    data() {
        return {};
    },
// OR
    asyncComputed: {
        test() {
            return Promise.resolve('hey');
        }
    },

Tagging @michaelzangl as this seems to be related to #45.

"Auto install in dist mode" code

This is so bad if you want to import vue from cdn and use this plugin options.

if (typeof window !== 'undefined' && window.Vue) {
  // Auto install in dist mode
  window.Vue.use(AsyncComputed)
}

I had to copy and manually remove this part to use it in my environtment.

I think this should change in future versions.

Document potential issue with dependency not being bound to the computed property

Hello, nice project!

I'd like to give my input on a potential issue one may encounter if he doesn't understand the logic behind VueJS dependencies. The following code will not update the asynchronous property on username change:

export default {
  data () {
    return {
      username: 'Yovar'
    }
  },
  asyncComputed: {
    greeting () {
      return new Promise(resolve =>
        setTimeout(() => resolve('Hello ' + this.username + '!'), 1000)
      )
    }
  }
}

From my understanding VueJS uses getters on the component's properties to detect if they are accessed between the invocation and the return of a function. In this scenario the setTimeout callback is invoked after the return of greeting. The greeting function should be writed as follows:

    greeting () {
      const username = this.username
      return new Promise(resolve =>
        setTimeout(() => resolve('Hello ' + username + '!'), 1000)
      )
    }

This way, the username property is accessed at a good moment for VueJS to understand the relation between this property and greeting.

I think it might be a common pitfall for JS beginners.

Here is a last example showing how hard it can be to debug using async/await. In this scenario changing locale will update greeting but changing username won't:

const texts = {
  en: {
    greeting: 'Hello {0}!'
  },
  fr: {
    greeting: 'Bonjour {0} !'
  }
}

function getLocalizedText (locale, text) {
  return new Promise(resolve =>
    setTimeout(() => resolve(texts[locale][text]), 1000)
  )
}

function format (pattern, parameters) {
  let index = 0
  parameters.forEach(parameter => {
    pattern = pattern.replace('{' + index++ + '}', parameter)
  })
  return pattern
}

export default {
  data () {
    return {
      username: 'Yovar',
      locale: 'fr'
    }
  },
  asyncComputed: {
    async greeting () {
      const pattern = await getLocalizedText(this.locale, 'greeting')
      const formatted = format(pattern, [this.username])
      // Notice how the two instructions are on the same level.
      // Without a deep understanding of async/await it's pretty hard to understand the property not getting updated on `username` change.
      return formatted
    }
  }
}

Cheers.

Error when importing component which uses AsyncComputed

I created a component which uses vue-async-computed. However when importing that component into another Vue instance I get an error in vue-async-computed.js?0f91:47:

Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.remoteFunction

I am not sure whether this is an issue with vue-async-computed or not, apparently it might be an issue with Babel. However when importing and using vue-async-computed inside the new Vue instance it works fine. Any idea what could be the reason for that?

pass parameters

When I pass the parameter, the final retrun value is empty.
The code is as follows:
html:
市场平均价格{{computedAverage(2048,val.adzone_id)}}元
js:
asyncComputed: {
computedAverage:{
get () {
return function(itemId,resourceId) {
this.$http.get('/zuanzhan/price/suggest', {
params: {
target_type: itemId,
adzone_id: resourceId
}
}).then((res)=>{
console.log(res.data.data.price)//24.5
return res.data.data.price//empty?
})
}
},
}
},

New release on npm

Since the addition of the shouldUpdate feature there hasn't been a release. Could you please release a new version?

Feature request - lazy load

I expected the computed getter to only fire when the getter is accessed. Do you think it's implementable as an option? { lazy: true }

I was able to implement the behaviour, but had to change a lot:

const prefix = 'async_computed$'

const AsyncComputed = {
  install (Vue, options) {
    options = options || {}

    Vue.config
      .optionMergeStrategies
      .asyncComputed = Vue.config.optionMergeStrategies.computed

    Vue.mixin({
      data () {
        if (this.$options.asyncComputed) {
          return {
            async_computed$: {}
          }
        }
        return {}
      },
      beforeCreate () {
        if (!this.$options.asyncComputed) {
          return
        }

        const optionComputed = this.$options.computed

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

        const computed = (
            (typeof optionComputed === 'function')
              ? optionComputed.call(this)
              : optionComputed
           ) || {}

        // Add computed getter for each key
        Object.keys(this.$options.asyncComputed || {}).forEach(key => {
          computed[key] = function () {
            if (typeof this.$options.asyncComputed[key] !== 'function') {
              return this.$options.asyncComputed[key]
            }

            if (!this['_request$' + prefix + key]) {
              this['_request$' + prefix + key] = true

              // Call computed property
              this.$options.asyncComputed[key]()
                .then(value => {

                  // This will trigger watchers of the computed property
                  // because a default value was set in $data
                  this[prefix][key] = value

                  // Hacky way of allowing to trigger again
                  // Should use throttle-like function instead
                  setTimeout(() => {
                    this['_request$' + prefix + key] = true
                  }, 25)
                })
                .catch(err => {

                  // Error handler
                  const handler = (options.errorHandler === undefined)
                    ? console.error.bind(console, 'Error evaluating async computed property:')
                    : options.errorHandler

                  if (options.useRawError) {
                    handler(err)
                  } else {
                    handler(err.stack)
                  }
                })
            }

            // Return computed value
            return this[prefix][key]
          }
        })
        this.$options.computed = computed
      },
      created () {
        if (this.$options.asyncComputed) {

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

export default AsyncComputed

// Auto install in dist mode
if (typeof window !== 'undefined' && window.Vue) {
  window.Vue.use(AsyncComputed)
}

Can't prefix with underscore

I've been using things like mapGetters() to import a list of getters, some of which are asynchronous, and so I'd like to use something like this:

asyncComputed: {
  _eventMembers () {
    return this.eventMembers
  }
},
computed: {
  ...mapGetters(['eventMembers'])
}

But this doesn't work. If I reverse the naming like this:

asyncComputed: {
  eventMembers () {
    return this._eventMembers
  }
},
computed: {
  ...mapGetters({'_eventMembers': 'eventMembers'})
}

it does work, but then I have to use the 'long' (object) form for mapGetters(), and I often have lots of those. Is there some reason why underscore can't be used as the first character of an asyncComputed property, or is it a bug?

Tx.

'default' keyword

'default' is javascript keyword, so es-lint failed with 'Parsing error: Unexpected token' error. I think it's better to use another key for this, like 'defaultValue'.

[email protected],use has error

use create dialog,with this way
import Vue from 'vue'
let DialogConstructor = Vue.extend(require('./main.vue'))

let instance;

var Dialog = function(options) {
instance = new DialogConstructor({
data: options
});
instance.vm = instance.$mount();
document.body.appendChild(instance.vm.$el);
instance.vm.show = true;
return instance.vm;
}
export default Dialog;

can not execute async-computed

set value when loading

Custom default value, which will be used until the data is loaded for the first time, but however, how can i set loading value every time with this plugin.
Example, how can i set loading status after i click a btn, and before async data is prepared

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.