Cannot read properties of undefined (reading 'find') in Vue.js Meteor

Viewed 133

Im following the tutorial here... https://vue-tutorial.meteor.com/simple-todos/

But I get an error even just when installing the default vue meteor app.

meteor: {
$subscribe: {
  'experiments': [],
},
experiments () {
  return Experiments.find({}).fetch();
},

},

gives me an error

TypeError: Cannot read properties of undefined (reading 'find')"

If I console log Experiments, its there and I get the Meteor collection object. Any idea why this might be occuring??

import Experiments from '../../api/collections/Experiments'
console.log(Experiments)

Gives me

enter image description here

So its obviously an available object.

Just the find({}).fetch() method on it doesnt seem to be available??

UPDATE:

THE ANSWER BELOW WORKED (kind of)

experiments() {
  let experimentsData = Experiments.find({}).fetch();
  if (this.$subReady.experiments) {
    console.log(experimentsData);
    return experimentsData;
  }
},

This now returns the experiments in the console log. So they are available. However rendering them to the template doesnt.

<h2>Experiments</h2>
<div v-for="exp in experiments" :key="exp.id">
  {{exp.name}}
</div>

Any idea why?? Does it have to be put into a vue data object? Computed?? I thought the meteor:{} object acted kinda like computed, but it appears not??

How do I get the data onto the screen??

2 Answers

It looks like you need to just use this.$subReady in your 'experiments` function to handle the timing of how the data comes in over DDP in Meteor.

I use something like this in all my subscriptions.

When the subscription starts up, the data won't be delivered from the publication the very 1st time, so that is what causes your undefined error that you are getting.

I love the Vue + Meteor combo. You can also come join the community Slack or Forum if you have questions, there are a bunch of us to help you there.

Happy Coding!

Bob

experiments () {

  let experimentsData = Experiments.find({}).fetch();

  if(this.$subReady.experiments){
        return experimentsData;
   }
},

This should resolve your issue in the UI. The HTML data will load and run before all the data from Meteor is ready, so you just use something like this:


   <h2>Experiments</h2>
   <div v-if="subReady.experiments" v-for="exp in experiments" :key="exp.id">
     {{exp.name}}
   </div>

The answer is actually not correct.

I am experiencing the same issue from an out of the box meteor vue app created with: meteor create vanillaVueMeteor --vue

The error occurs if you define ANY function in the meteor: section of the default export (and bizarrely the first function defined is always being called regardless of whether it is actually referenced anywhere). This is obviously a bug either in the meteor vue creator or some combination of the default versions of meteor and vue libraries.

Additionally with respect to providing data to your template: you should not call fetch, just pass the result of the find which then means you won't need to wait for the subs to be ready because reactivity will update the view when the data is available. Obviously the underlying issue is preventing this all from working correctly.

UPDATE: It seems to be an issue with 2.7.x Downgrading to the latest 2.6 worked for me: meteor npm remove vue meteor npm i vue@2.6 --save

Related