Code Monkey home page Code Monkey logo

vue-meteor-tracker's People

Contributors

akryum avatar buhrmi avatar gustawdaniel avatar voluntadpear 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-meteor-tracker's Issues

Tracker nonsense, help plz

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

Meteor autorun goes into an infinite loop.

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

data.property will break

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

dynamic $subscribe name?

       props: ['subscribeName'],
        meteor: {
            $subscribe: {
                [this.subscribeName](){
                    return ........;
                }
            },
            tableData(){
                console.log(Posts.find({}).fetch());
            },
        },

Meteor properties over reactive?

<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:

  1. 'test1' is triggered once - OK
  2. 'test2' is triggered once when '$lazy' is true and twice when '$lazy' is false - NOT OK

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.

Suggestion: setters on meteor data

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.

Data passed as props to component is not reactive

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>',

Reactive data / subscriptions (i.e. based on route params)

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?

TypeError: Cannot redefine property: $subReady

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?

$subscribe is not reactive based on other data

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 !

Meteor data not triggering `watch` and `computed` dependencies (v2.0.0-beta.3)

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 :)

Watchers breaking computed property

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!

Vue Meteor Tutorial and reactivity not working in v-for? (example repo included)

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!

currentUser global Blaze helper as global Vue mixin

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 calling Meteor.users.findOne(Meteor.userId()), and the {{currentUser}} Blaze helper that returns the value of Meteor.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.

$subReady returning false when function is used in $subscribe

@Akryum

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

Default values being overwritten with undefined

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`

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.

Is it possible to use meteor data inside subscriptions.

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.

Why other subscription call, Which do not need?

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.

Example for using cursor.observeChanges in a Vue component

I could not find any example of how to use cursor.observeChanges in a Vue component.

Reason

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.

Readme update?

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?

`Watcher` don't work?

meteor: {
    $subscribe: {
      ['app.company']: [],
    },
    company() {
      return Company.findOne()
    },
  },
watch:{
   company:{
      handler(val){
           // don't work
      },
      immediate: true,
   }
}

Warn: Cannot read property 'push' of null ( in v2.0.0-beta3 )

1st Issue:

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 :

this._trackerHandles.push(handle)

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 = [];

2nd issue:

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:

if (hasProperty(this.$data, key) || hasProperty(this.$props, key) || hasProperty(this, key)) {

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)

Unable to use multiple autoruns in two diffirent computed functions

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.

`ready` not documented?

I noticed a reference to ready() in the README, but it's not otherwise documented. Could we get more details on this?

Performance: unwanted executions of transform() function

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!

Warn "Error: Meteor data 'subscribe' ( in v2.0.0-beta3 )

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 ...

supply.js

capture d ecran 2018-05-21 a 15 28 06

console.log from supply/base.js:

capture d ecran 2018-05-21 a 15 15 03

Error :

capture d ecran 2018-05-21 a 15 26 44

Do you have any idea ?

EDIT: it works with beta 2.0.0-beta.1

Pass variable into MeteorData's query

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?

$autorun should rely on reactive property to work

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.

Add official way to override subscribe function

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.

Problem with `Element UI loading` for `Update form`

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

2017-05-03 14_53_10

Question: Is it possible to test meteor statement in Vue component ?

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 ?

Fast resubscribe local cache not cleared

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

$lazy: true causing Error in beforeCreate hook: "TypeError: Cannot read property '***' of undefined"

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

findOne(_id) cursors do not work with meteor collection hooks

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');
    }
}

Computed property with subready in it is not working. Watch on subready is not working either.

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.

$subReady always false

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...

Reactive vue component's properties are not reactive within "reactive" meteor properties in beta-3

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

Integration between Vue reactivity and Tracker reactivity

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:

  • for Meteor Vue components (or it could be an optional mixin), we could make it so that when Vue augments data with getters, we make them also Tracker getters (so when you set it, you invalidate both Vue and Tracker dependencies)
  • we could monkey-patch Vue Dep to make it interact with Tracker.Dependency, APIs are really similar
  • but we probably do not care really that changes which happen inside Tracker dependencies are run on Tracker queue, we probably only want to provide the same API to reactive Meteor code so that it thinks it is running inside autorun, but it fact it is interacting with Vue Dep (and we leave to Vue to run it inside its own queue); this means that inside Vue, we could maybe misuse Tracker.active to set it to a fake computation which interacts with current Vue Dep
  • for Minimongo integration, I wanted for a long time to make something there which would make it so that it is not needed to specify fields 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 Vue
  • we should see how Vue wraps mutation objects on arrays and make it so that Minimongo changes trigger those mutations on Vue

What are your thoughts what is missing here for proper Meteor integration?

Meteor subscriptions seems not to be stopped

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!

Don't work with `Collection Null (Local)`

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)

Errors in publications aren't handled properly

Using the $subscribe function with Vue dynamic arguments doesn't work properly if the publication throws an error.

  • The previous subscription (which didn't have an error) is not stopped, so the data persists client-side.
  • There is no way to display or otherwise react to the error on the client.

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.

subsReady hook?

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.

Pub/Sub run in local it work fine but on server cloud not working?

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

[Request] Import/require Tracker dependency

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()

Check if all subscriptions are ready?

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?

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.