meteor-vue / vue-meteor-tracker Goto Github PK
View Code? Open in Web Editor NEWUse Meteor Tracker reactivity inside Vue components
Use Meteor Tracker reactivity inside Vue components
[Vue warn]: Error in created hook: "Error: You must provide either a function or an object with the update() method."
data: {
listings: {
params() {
return {stuff: this.name}
},
update ({param}) {
if(param.length != 0){
return AuctionItems.find({name: param.stuff, active: false, topBid: {$exists: true}}).fetch()
} else {
return ["none"]
}
return {sd: 1}
}
},
}
Hi,
I am using the latest meteor and meteor-vue-tracker and I am facing an issue in which a meteor property keeps getting called infinitely and slows down the whole project.
I have created this repo to reproduce the issue. There are 4 links provided in the project. They are organisations(list of organisation), organisation dashboard (currently displays only the organisation name), OrganisationRoles (roles list) and Organisation stocks. OrganisationRoles is the only page where there is no subscription. If you go to organisationRoles page and move back to organisationDashboard page then it seems meteor autorun written in the package goes into an infinite loop. This can be confirmed by looking in the console. I have added a console log inside the meteor property, which finds organisation based on route id inside the organisation dashboard. You can see this keeps logging infinitely.
To login use the following credentials:
email - [email protected]
password - password
If in case you are unable to reproduce the issue create a new role and navigate between the routes a few times. Keep the console open at all times.
Kindly look into this as this is happening at lots of places in our project and is a blocker.
Would appreciate if you can take out some of your time and get it fixed.
Thanks,
Abhimanyu
I can't tell if it only happens on page refresh, but using db.found.property or using that in v-for or {{ }} will break client. I used another way, but probably using vue data field with || operator to access meteor data property is better way getting it unless the || operator won't auto update to use meteor data.
PS this is about findOne that doesn't appear to care if you selected a field in find params
props: ['subscribeName'],
meteor: {
$subscribe: {
[this.subscribeName](){
return ........;
}
},
tableData(){
console.log(Posts.find({}).fetch());
},
},
<template>
<div v-if='test1'/>
</template><script>
export default {
computed: {
test1 () {
console.log('test1')
}
},
meteor: {
$lazy: true,
test2 () {
console.log('test2')
}
}
}
</script>
In the above example:
Expected behaviour:
The 'test2' should not trigger at all when '$lazy' is enabled, or be triggered only once when $lazy is disabled.
Notes:
'Vue.config.meteor.freeze = true' does not fix it either.
Since meteor reactive data are basically computed properties, it would be nice if they could also have setters so that they could be used natively inside v-model
. e.g. It would be nice to do this:
meteor: {
optedOut: {
get() {
return Meteor.user().optedOut;
},
set(value) {
Meteor.call('setOptOut', value);
},
}
}
Instead of having to use $autorun
inside computed
like this:
computed: {
optedOut: {
get() {
return this.$autorun(() => Meteor.user().optedOut);
},
set(value) {
Meteor.call('setOptOut', value);
},
}
}
I know there's not much difference, but it took me a thorough reading of the documentation to learn about the $autorun
function and using Meteor data without the meteor
option. Whereas the getter
and setter
syntax seemed more natural to me and I was surprised that they weren't there when I looked for them in the docs. It would also keep all the meteor data together within the meteor
block instead of split between meteor
and computed
.
Just a suggestion though - I'm loving this (and your other vue-meteor packages), thanks!
If you don't take this suggestion, then instead it would be good to use an example with a setter in your docs, so that users can find this functionality more easily in your docs.
Version: 2.0.0-beta.3
Vue version: 2.5.16,
OS: Ubuntu,
Browser: Chrome
I noticed that data passed as props to child component is not reactive.
According to doc: All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child
Example:
Data will populate after meteor subscription finish
{{dataFromSubs}}
<my-component v-bind:msg="dataFromSubs"></my-component>
But in props, the changes are not reflecting
props:['dataFromSubs'],
template: '<h1>{{dataFromSubs}}</h1>',
I'm trying to get a reactive list of data based on a route param. I have this:
meteor: {
subscribe: {
messages() {
console.log('subscribe', this.$route.params.term);
return [ this.$route.params.term ];
},
},
messages() {
console.log('messages', this.$route.params.term);
let searchTerm = this.$route.params.term;
let query = { title: searchTerm };
return Messages.find(query);
},
},
This works fine on initial load. However, when navigating (and thus changing the term
route param), the messages vanish. By looking at the log, I can see that only the subscription was reactively updated, not the data itself (the messages
function did not run again).
How come? What do I need to do make the data reactive?
I am receiving the following TypeError: Cannot redefine property: $subReady
The error stack is:
at Function.defineProperty ()
at VueComponent.firstPrepare (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:43927)
at callHook (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:30503)
at VueComponent.Vue._init (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:32208)
at new VueComponent (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:32380)
at createComponentInstanceForVnode (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:31892)
at init (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:31713)
at createComponent (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:33190)
at createElm (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:33137)
at VueComponent.patch [as patch] (modules.js?hash=efa19dc1a6f0d0ead424b960075ceae573106eab:33673)
It seems like the package is trying to redefine an already existing Object.property while preparing the vue instance for rendering.
Any ideas how to prevent this error?
Version: 2.0.0-beta.3
Vue version: 2.5.16,
OS: Ubuntu,
Browser: Chrome
Subscriptions inside $subscribe is not reactive ?
for example:
On page load, it takes a few seconds for subscribe data to get published and send to frontend.
$subscribe: {
'food': function(){
// drink data here is not reactive
let drink = Drinks.findOne({user_id: Meteor.userId()});
return [ {drink_id: drink._id} ];
}
},
drink: function(){
// drink data here is reactive
let drink = Drinks.findOne({user_id: Meteor.userId()});
return drink;
}
Anyone facing this issue ? Or my way is wrong ?
Please advise. Thanks !
Excuse me, could you explain "You may need to polyfill Object.assign"
After updating from v1.2.3, I am much happier about the cleaner code and reduction of redundant data
keys. However, there are a couple of Vue modules that are no longer working as before and I tracked them down to having watch
and computed
values that depend on the keys that were previously listed in data() { return { foo: ... } }
but are now generated by meteor: { foo: ... }
.
All template code that depends on the meteor
data keys still work fine.
Is this a bug or something I'm doing wrong? Happy to create a reproduction but wanted to quickly check if this was an actual issue first.
EDIT: just saw that the computed
code was added in beta.3. Maybe it needs some tests :)
I might have found an issue when using watchers on computed properties including meteor data.
To illustrate, take the following example (using the VueMeteor demo app):
In the Notes.vue Component we'll be adding a watcher for the firstNote()
computed property.
watch: {
firstNote(val) {
console.log(val)
}
}
After adding the watcher, the computed property will not compute, as this.notes
is undefined in the computed property for some reason.
The same can be observed for another another example:
computed: {
notesCount() {
return this.notes ? this.notes.length : -1;
}
}
This computed property will compute just fine, but as soon as we add a watcher to observe changes in the item count, it will break, meaning it will not recompute and always show -1.
watch: {
notesCount(value) {
console.log(value)
}
}
This behavior can be fixed with the following:
computed: {
notesCount() {
return this.$subReady.notes ? this.notes.length : -1;
}
}
Using this computed property, the code will behave as expected, updating the count of items and printing it to the console through the watcher whenever it changes.
Maybe this is something to look into as I think the first example should behave in the same way as the latter.
This issue might be related to #34.
Reproducing example repo https://github.com/paulschwoerer/meteor-vue-tracker-watcher-error-example
Cheers!
Hey there,
I put together a repo with a simple-todos for Vue using Meteor 1.8: https://github.com/MichaelJCole/simple-todo-vue
Once the code's complete, I can package it up into the Tutorial.
It's almost working except for some reactivity when:
Clicking "Hide completed tasks"
Checking a todo as done/not done
Clicking Private/Public on a todo.
Delete and add work great. I hacked up a Blaze integration for accounts-ui similar to the React tutorial.
I think Meteor is reactive, but it's not updating Vue correctly, or it's specifically the Vue v-for.
Any suggestions on how to get the reactivity to work?
Thanks in advance!
For code that runs on the client, the global
Meteor.userId()
reactive function will give you the ID of the currently logged in user.In addition to that core API, there are some helpful shorthand helpers:
Meteor.user()
, which is exactly equal to callingMeteor.users.findOne(Meteor.userId())
, and the{{currentUser}}
Blaze helper that returns the value ofMeteor.user()
.
The {{currentUser}}
is of course unavailable in Vue and Meteor.user()
is available only inside of meteor
option.
I'm wondering if this package shouldn't come by default with a simple global mixin that reactively provides both this.currentUser
with {{currentUser}}
and this.userId
or this.currentUserId
.
Below the problem that I am facing:
meteor: {
$subscribe: {
'Time': [],
'Organisation': [],
'OrganisationData' () {
return [this.organisationIds]
}
},
OrganisationCursor () {
return Organisation.find({})
},
organisationIds: function() {
this.OrganisationCursor && this.OrganisationCursor.map((organisation) => organisation._id);
}
}
I have passed a meteor reactive property as an argument to OrganisationData
subscription. The publication on backend is called and returning data as well. But $subReady.OrganisationData
is always false.
Below is the link to the repository to reproduce the problem.
https://github.com/ashish979/meteor-vue-example
Any help would be appreciated.
Thanks
I have a problem where my default values are being overwritten by the meteor method call causing an error Cannot read property 'profile' of undefined at Proxy.About.vue.__vue_options__.render (About.vue:47)
in the console.
My component looks like this:
<template>
<div class="ui main container about">
<div class="ui two column centered stackable grid animated fadeIn">
<div class="ui one column center aligned">
<form class="ui form about-form" v-on:submit.prevent="sendEmail">
<div class="field image-field">
<h3 class="about-title">title.</h3>
<h4 class="about-description">yaay</h4>
<h2 class="about-call-to-action">Say Hello</h2>
</div>
<div class="field">
<input type="text" :placeholder="email" class="about-email" v-model="user.profile.email">
</div>
<div class="field fullname-container">
<input type="text" class="about-fullname" :placeholder="Fullname" v-model="user.profile.fullname">
</div>
<div class="field">
<div class="ui selection dropdown about-message-title">
<input type="hidden" name="gender">
<i class="dropdown icon"></i>
<div class="default text">I got an idea</div>
<div class="menu">
<div class="item" data-value="Idea">I got an idea</div>
<div class="item" data-value="Bug">Found a bug</div>
<div class="item" data-value="Product">Submit this product</div>
<div class="item" data-value="Business">Let's talk business</div>
<div class="item" data-value="Job">I am looking for a sideproject</div>
<div class="item" data-value="Other">Other</div>
</div>
</div>
</div>
<div class="field about-message-field">
<textarea type="text" :placeholder="Message" rows="6" class="about-message" v-model="message"></textarea>
</div>
<div class="field">
<button class="ui button blue send-message-button" :click.prevent="sendEmail">
Send
</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
metaInfo: {
title: 'About',
meta: [
{ vmid: 'description', name: 'description', content: '...' }
]
},
data() {
return {
message: "",
user: {
profile: {
email: 'default email',
fullname: 'default fullname'
}
}
}
},
meteor: {
user() {
return Meteor.user();
}
},
mounted() {
$('.dropdown').dropdown();
},
methods: {
sendEmail() {
...
}
}
};
</script>
<style lang="less" scoped>
...
</style>
After the error the user is being loaded and I can see the email/fullname in the form. But my dropdown does not work because of the error. If I remove the meteor tag everything works as expected and I can see "default email" and "default fullname" in the form.
So it seems like before my data is loaded my user object is being replaced with undefined
. Is there a workaround for this? Thanks
Problem with dynamic prop on $subscribe
data() {
return {
param: '',
posts:[],
},
meteor: {
$subscribe: {
postsPub(){
return [this.param];
}
},
posts(){
return Posts.find().fetch();
},
},
methods:{
handleParamChange(){
// change param.......
}
}
When I change param
multi time, It get Posts
in correct.
I updated vue-meteor-tracker to the latest version. Now I am facing issues with the code I had with the previous version.
Previous Code:
export default
data: ->
friendIds: null
meteor:
friendIds: -> (friend._id for friend in Friends.find().fetch())
$subscribe:
'friendsData': -> [@friendIds]
The subscription above was working fine with the older version.After upgrdaing I got the following error
friendIds: Property already used in the component data, props or other.
I removed friendIds from data as shown below:
Code after upgradation
export default
meteor:
friendIds: -> (friend._id for friend in Friends.find().fetch())
$subscribe:
'friendsData': -> [@friendIds]
Now the subscription is not working properly. Subscription is getting called once with null as params.
Is it possible to use meteor data inside subscriptions? If not what would be the best approach to solve the above issue.
Thanks in advance. Any help would be appreciated.
Step 1: Call a subscription and closed the subscription after my work.
Step 2: Call other subscription. Then call step2 subscription and with step1 subscription. It's not dependancy of the step1 subscriptions. But why call step1.
I want to actual subscription not other subscription. Please help me.
I could not find any example of how to use cursor.observeChanges in a Vue component.
I have a component encapsulating a interactive data visualization. This visualization is not reactive, the data it relies on needs to be transformed first and the layout will be computed subsequently . On the other hand it is possible to perform efficient atomic operations to modify the layout afterwards. This is where cursor.observeChanges comes in handy.
Basically I need automatic subscription with dynamic parameters which will be re-called reactively when the container component props changes. When the subscription is ready I need to create a cursor with dynamic parameter and observe the changes with the observeChanges method.
Is updated this indication in the readme?
Note: if you are using the Meteorย akryum:vueย package, you don't need to install the plugin.
I've follow the link but akryum vue is a collection of package. To what package is referred?
meteor: {
$subscribe: {
['app.company']: [],
},
company() {
return Company.findOne()
},
},
watch:{
company:{
handler(val){
// don't work
},
immediate: true,
}
}
When I enter in a vue component using a registered vue-supply (with subscribes) , I get that error:
Cannot read property 'push' of null
This error comes from this line :
vue-meteor-tracker/src/index.js
Line 136 in 6f6a143
this._trackerHandles is equal to null, and I couldn't find any reason.
in $stopMeteor method, this._trackerHandles is set to null, but it didn't get called.
Maybe we could do something like : if (!this._trackerHandles) this._trackerHandles = [];
Vue component seems to have a cache.
1/ I load for the first time a component, everything works fine.
2/ Then, I leave this component by going to another route (so component is destroyed)
3/ Finaly, I come back into my inital component (changing route again)
Meteor data '${key}': Property already used in the component data, props or other
This error comes from this line:
vue-meteor-tracker/src/index.js
Line 229 in 6f6a143
and more specificly from this statement : hasProperty(this, key)
My vue component already know key
property
I think we should only check for (hasProperty(this.$data, key) || hasProperty(this.$props, key)
I was trying to use this code:
computed:{
messages(){
let self = this;
if(this.$subReady.messages){
console.log(Meteor.user().username + " and " + self.link);
return this.$autorun(function() {
Meteor.call("setCheckedDuo", {"opponent": self.link, "id": Meteor.userId()})
return Messages.find({}, {
sort: { created: this.sort ? -1 : 1 },
})})
}
},
opponentOnline(){
if(this.$subReady.userStatus){
return this.$autorun(() => {
return "testing"
})
}
}
},`
But it starts loop and send about 500-600 request to the server. If i will just remove opponentOnline function or messages function, everything will work as should be. How to fix this? I've tried to remove node_modules and download again, nothing.
I noticed a reference to ready()
in the README, but it's not otherwise documented. Could we get more details on this?
I tried setting it to true, and everything still updates as it should. But since it's not the default, I assume it must cause problems in some cases?
Hello!
I use collections/cursors with defined transform()
function to transform raw documents to class instances. Normally, this function is executed when a document is fetched for the 1st time or updated. But with vue-meteor-tracker
it's re-executed for all matching documents if one of them has been changed. Please, take a look at the code:
<template>
<main>
<div v-for="note in notes">
{{ note.text }}
</div>
</main>
</template>
<script>
import Notes from '/imports/Notes'
export default {
meteor: {
$subscribe: {
'notes.all': []
},
notes() {
return Notes.find({}, {
transform(note) {
console.log('transformed');
return note
}
})
}
}
}
</script>
// server.js
create7Notes()
// later
updateSingleNote() // => 7 'transformed' messages in the browser
As you see, each note is transformed again even if it wasn't updated. That might be a problem for the large datasets. I tried the same scenario in Blaze using {{#each .. in}}
helper and everything works as expected: transfom()
is re-executed only for the updated document.
Is this an expected behavior for vue-meteor
? Is there a way to change it?
Thank you in advance!
Hello,
We just tried last version of meteor-vue-tracker (beta3).
A package seems to add a subscribe property into meteor statement but we dont know which one.
We are using vue-supply, meteor-vue-tracker and vuex together.
Of couse, we inspected all files, we couldn't find any subscribe property anywhere ...
Do you have any idea ?
EDIT: it works with beta 2.0.0-beta.1
Hi,
Thanks for som great updates to this libraray.
Im trying to do this:
<div class="column" v-for="id in data.listItems" :key="id">
<MeteorSub name="productByReadableId" :parameters="[parseInt(id)]" >
<template slot-scope="{ loading }">
<MeteorData
:query="getProduct(id)"
class="product">
<template slot-scope="{ data: product }">
{{product}}
</template>
</MeteorData>
</template>
</MeteorSub>
</div>
And then:
methods: {
...
getProduct(id) {
return Products.findOne({ readableId: id });
}
},
Which gives me the following error:
Invalid prop: type check failed for prop "query". Expected Function, got Undefined
If I remove the parameter and hardcode my id in the findOne
function it works as I expected. Is there any way to pass a variable into my getProduct function?
{{!$subReady.posts}} // work fine
{{loading}} // don't reactive
----------
data() {
return {
loading: true
};
},
meteor: {
$subscribe: {
posts: []
},
loading(){
return !this.$subReady.posts;
},
Recently I decided to switch to using computed properties returning this.$autorun()
instead of meteor
property, because of this #49 issue. But encountered another issue. Computed property returning this.$autorun()
becomes reactive only if it has any reactive property (data or props) inside function body. Here are two examples illustrating the issue:
<!-- non-reactive example, always 0 -->
<template><div>{{ nonReactiveItems.length }}</div></template>
<script>
const Items = new Mongo.Collection(null)
Meteor.setInterval(() => { Items.insert({}) }, 2000)
export default {
computed: {
nonReactiveItems() {
return this.$autorun(() => Items.find())
}
},
}
</script>
<!-- reactive example -->
<template><div>{{ reactiveItems.length }}</div></template>
<script>
const Items = new Mongo.Collection(null)
Meteor.setInterval(() => { Items.insert({}) }, 2000)
export default {
data() { return { anything: undefined } },
computed: {
reactiveItems() {
this.anything // This line enables reactivity
return this.$autorun(() => Items.find())
},
},
}
</script>
Now the question is whether it is an issue at all? The only provided example in docs relies on reactive this.sort
property, so probably it is an expected behavior? If so, we should update the README to make it clear.
Could you add an official way to override the subscribe
function? I'm currently using v1.2.3, and I implement my own override like so:
Vue.config.meteor.subscribe = function (index, publication) {
if (typeof publication === 'string') {
return Meteor.subscribe(publication);
}
return publication.subscribe();
};
The reason for this is that I use my meteor-publication
package, which lets me avoid using magic strings for the publications (I use it in conjunction with TypeScript to enforce the parameter types passed to the publications):
import slideThumbnailPublication from '../publications/slideThumbnail';
//...
meteor: {
$subscribe: {
subscribedThumbnail() {
return [slideThumbnailPublication.withData(this.slide._id)];
},
},
//...
If possible, I would like an official way to override the subscribe function so I don't have to worry about it not being possible at all in future versions.
I tried with Loading of Element UI
with Update Form
.
<div v-loading.body="!$subReady.posts">
<el-form :model="form" :rules="rules" ref="form" label-width="150px">
<el-form-item label="Title" prop="title">
<el-input v-model="form.title"></el-input>
</el-form-item>
<el-form-item label="Body" prop="body">
<el-input type="textarea" v-model="form.body"></el-input>
</el-form-item>
<el-form-item label="Type" prop="type">
<el-select
v-model="form.type">
<el-option label="Public" value="Public"></el-option>
<el-option label="Private" value="Private"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Created date" prop="createdDate">
<el-date-picker
type="date"
v-model="form.createdDate">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')" :loading="submitLoading">Submit</el-button>
<el-button @click="resetForm('form')">Reset</el-button>
</el-form-item>
</el-form>
</div>
---------------
export default {
name: 'PostEdit',
data() {
return {
submitLoading: false,
form: null,
rules: {
title: [
{required: true}
],
body: [
{required: true}
],
type: [
{required: true}
],
createdDate: [
{required: true}
],
}
};
},
meteor: {
// Subscriptions
$subscribe: {
// Subscribes to the 'threads' publication with no parameters
posts: function () {
let _id = this.$route.params.id;
return [{_id}];
}
},
form(){
return Posts.findOne({_id: this.$route.params.id});
},
},
I work, but have problem with UI
show
Hello,
I'm looking for help.
I would like to test methods in meteor statement :
exemple :
export default {
name: 'component',
meteor: {
user() {
return Meteor.user();
},
},
};
Test :
import { mount } from '@vue/test-utils';
import component from '../index.vue';
describe('component', () => {
test('Should init computed methods', () => {
const user = {};
const wrapper = mount(component);
const vm = wrapper.vm;
expect(vm.user).toEqual(user);
});
});
vm.user is always undefined.
If I change put user method in a computed statement, it works.
Any idea ?
When reactive param changes very fast in subscription, updates not received. At server side all working fine and with fast resubscribe it return correct data to client. But at the client side - cache from last subscription not cleared, causing local data to be not updated (or maybe something else happens, but i'm sure it's an issue).
Example users collection (getAllUsers not updated after fast resubscribing):
meteor: {
$subscribe: {
'allusers': function(){
return [this.currentPage];
}
},
getAllUsers: function(){
return Meteor.users.find({}, {sort: {createdAt: -1}, limit: 10});
},
}
If a meteor property relies on any props or other component data or computed properties, it causes an error when used with $lazy: true
. It seems that the function is being called within the beforeCreate
hook at which point the other data doesn't exist yet.
e.g:
props: ['userId'],
meteor: {
$lazy: true,
avatar() {
console.log(this.userId); // [Vue warn]: Error in beforeCreate hook: "TypeError: Cannot read property 'userId' of undefined"
const user = Meteor.users.findOne({_id: this.userId}, {fields: {"profile.avatar": 1}});
return Meteor.absoluteURL('avatars/'+user.profile.avatar);
}
}
My work-around is to do this instead:
props: ['userId'],
computed: {
avatar() { () => { return this.$autorun(() => {
console.log(this.userId); // no problem
const user = Meteor.users.findOne({_id: this.userId}, {fields: {"profile.avatar": 1}});
return Meteor.absoluteURL('avatars/'+user.profile.avatar);
})}
}
Actually one publication may have more than one subscriptions (ie: different arguments), but under current design we cannot do that.
I use a few before.find and before.findOne hooks from https://github.com/matb33/meteor-collection-hooks. And they only work outside of the vue meteor tracker. E.g.
If I have hook:
Projects.before.findOne(function (userId, selector, options) {
selector.removed = null
});
This will work:
methods: {
findProject () {
return Projects.findOne('xyz')
}
}
This will work:
meteor: {
project () {
return Projects.findOne({_id: 'xyz'});
}
}
This will not work:
meteor: {
project () {
return Projects.findOne('xyz');
}
}
I have a case where a subscription should take place only when the other subscription is ready.
I could not find any subscription ready hook in the documentation. So I tried a few things with the following code but faced the problems mentioned in the comments.
export default
data: ->
filter: null
computed:
filterSubscriptionReady: ->
#this gets called when the filter subscription changes.
@$subReady.filter
userSubscriptionReady: ->
# this gets called only once and the value does not change even when $subReady.users changes.
@$subReady.users
meteor:
$subscribe:
filter: []
filter: -> Filter.findOne()
watch:
'$subReady.filter': (value) ->
console.log('this watch is not working')
if value
@$subscribe('users', @filter)
'$subReady': (value) ->
console.log('this watch is not working either')
'filter': (value) ->
# this will work but i can not use this as I need the below subscription to run even when there is no filter in the db.
if value
@$subscribe('users', @filter)
I can do null handling in publication but in the above case when filter is not present, there is a default value for filter in the publication.The problem is when the filter subscription is not ready users data is returned with default filter value. The users subscription gets called again when the filter subscription is ready.
Note: The above case is not exactly the same as I am facing in the project so I apologize if I missed something and the question is not clear.
I am brand new to the vue + meteor stack, so forgive me if this is a dumb question.
I am having trouble retrieving any db data. $subReady is always false and queries are returning empty data.
Being new to both meteor and vue I am not able to find where I am going wrong. May be simple, but is escaping me. Any help will be greatly appreciated.
I am trying to get the basics of retrieving and displaying static data as well as reactive. Most example I find are different file structures and short on a the full function flows, so it's tough for a new comer to trace and relate.
// export default //
data () {
return {
newNote: '',
limit: 5,
sort: true,
selectedTrekId: null
}
},
meteor: {
$subscribe: {
'treks' () {
return [this.limit]
},
},
treks () {
return Treks.find({}, { sort: { _id: -1 }})
},
// Selected thread
selectedTrek () {
// You can also use Vue reactive data inside
return Treks.findOne(this.selectedTrekId)
}
},
computed: {
allTreks () {
return this.treks
},
treksCount () {
return this.treks.length
}
},
watch: {
'$subReady.treks' (value) {
console.log('Watch - Subscription Ready: '+value)
},
},
have also tried the mounted method
`this.$subscribe('treks', 'new', 10);
console.log('Mounted - Sub Ready status: '+this.$subReady.treks)
Trying to display with
<p> Testing Reactive Var: {{allTreks}}</p>
<p>Testing Trek Count: {{treksCount}}</p>
<div v-if="!$subReady.treks">Loading...</div>
Results are
Testing Reactive Var: []
esting Trek Count: 0
Loading...
The reactive selectedThreadId
(be it either a prop or a reactive property within data), won't be updated within reactive meteor properties (but is reactive within each subscription under "$subscribe"), for example:
export default {
props: {
selectedThreadId: String
},
meteor: {
$subscribe: {
'threads' () {
// The "this.selectedThreadId" IS updated by Vue reactivity
console.log("1. this.selectedThreadId", this.selectedThreadId)
return[]
}
},
selectedThread () {
// The "this.selectedThreadId" IS NOT updated by Vue reactivity
console.log("2. this.selectedThreadId", this.selectedThreadId)
}
}
})
This happens only in latest v2.0.0-beta.3, but works ok in v2.0.0-beta.2
I am looking a bit how you are integrating Tracker with Vue and maybe I am misunderstanding something, it does not yet work as one would expect from perfect integration, because Vue reactivity is not really integrated with Tracker reactivity, no? So you cannot really use inside methods both Tracker reactive functions and access data and expect things to rerun, no?
Luckily, it seems that Vue reactivity has a similar model to Tracker reactivity. It also seems that Vue's state tracking is just a mixin.
Here are some random ideas what we could do:
data
with getters, we make them also Tracker getters (so when you set it, you invalidate both Vue and Tracker dependencies)Tracker.active
to set it to a fake computation which interacts with current Vue Depfields
on the query to limit reactivity, but it would be limited automatically by the fact that you would use some values and not others, it seems that this could be very well integrated with VueWhat are your thoughts what is missing here for proper Meteor integration?
Hi,
On my first project integrating vue.js with meteor, using akryum package (akryum:[email protected]), I realised today that meteor subscriptions seems not be stopped.
Passing a document Id through the vue-router as param, from a first component with meteor{}, to a component in another page without it, I can then simply use a computed property to call mycollection.findOne(id). I have no cache for subscriptions nor the insecure package.
Is that normal? I thought that the subscriptions would be stopped when the component calling them is destroyed (which I assumed was when it is not visible anymore).
Thanks for your excellent work!
I would like to use Collection Null (Local)
let CollectionNull = new Mongo.Collection(null);
export default {
data() {
return {form: { items:[] }};
},
meteor:{
'form.items'(){
return CollectionNull.find().fetch();
}
}
}
But don't work (Reactive Data)
Using the $subscribe
function with Vue dynamic arguments doesn't work properly if the publication throws an error.
In my app, this results in a situation where the subscription update fails silently (and $subReady
never updates), and then a new subscription without error results in both the data from the old and new subscription being displayed.
Not all subscriptions can be validated and guaranteed not to have an error client-side, so this creates a bit of a mess with regard to possible user error.
I need to execute code when the subscription is ready. Is there some onSubscriptionReady hook that I can use? I know that there is a $subReady reactive variable that I can use in the template, but I need it with a callback.
Hello, I have problem with publish and subscribe when run on local it work fine but I deploy on cloud server why it does not working. I don't know why? please help.
meteor: {
$subscribe: {
'pos.itemMovementAlert': function() {
return [this.currentBranchId]
},
},
productTransferNotify() {
let items = ItemMovements.find({
// toBranchId: this.currentBranchId,
transferBranchId: this.currentBranchId,
status: 'Open',
}).fetch()
console.log(items, this.currentBranchId)
let data = []
if (items && items.length) {
items.forEach(o => {
let doc = {
title: `Product Transfer : ${o.refNo} | ${moment(o.tranDate).format(
'DD/MM/YYYY'
)} | ${o.total} ${this.baseCurrency}`,
// icon: 'fas fa-bell fa-lg',
route: {
name: 'PosItemMovementAcceptForm',
query: { moveId: o._id, actionType: 'Open' },
},
}
data.push(doc)
})
}
return data
},
},
This may not be a typical use case, but I'm running unit tests for a Meteor app with Jest and circumventing Meteor's test command. If you were to change this package from using Tracker
as global to an imported/required dependency, I could mock its import with a moduleNameMapper
in jest.
So instead of just doing
Tracker.autorun()
It would be great if the dependency was explicitly imported/required
const { Tracker } = require('meteor/tracker');
....
Tracker.autorun()
I know you can check if a subscription is ready with the following:
this.$subReady.thread
But assume you have multiple subscriptions like below:
$subscribe: {
'subName1': [],
'subName2: [],
'subName3': [],
'subName4': [],
'subName5': [],
'subName6': [],
....
I want to check if all subscrptions are ready, otherwise I want to show a Loading text.
Ofcourse I can check:
let isReady = this.$subReady.subName1 && this.$subReady.subName2 && this.$subReady.subName3 ... && this.$subReady.subName6
Is there perhaps a simpler way to check if all subscriptions are ready?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.