This Meteor code failed to return the number of documents in Vehicles collection when console.log
in the client code. Please help find the problem where I went wrong. Thx
//imports/api/vehicles.js
import {Mongo} from 'meteor/mongo';
export const Vehicles = new Mongo.Collection('vehicles');
///////////////////////////////////////////
//server/publish.js
import {Vehicles} from '../imports/api/vehicles.js'
Meteor.publish('vehicles', function(){
return Vehicles.find({})
})
///////////////////////////////////////////
//server/main.js
import { Vehicles } from '../imports/api/vehicles.js';
//so I added this tying to fix the problem for no avail
Meteor.startup(() => {
Meteor.publish('vehicles', function () {
return Vehicles.find();
});
});
///////////////////////////////////////////
//client/main.js
import {Vehicles} from '../imports/api/vehicles.js'
Meteor.startup(function(){
Meteor.subscribe('vehicles');
console.log('subscribed') //<<<<<< prints "subscribed"
let rec = Vehicles.find({}).count()
console.log(rec) //<<<<<< prints "0"
})
///////////////////////////////////////////
Blaze collection findOne return no document
After reading the first response, in regarding Blaze will do it automatically, and I don't have to do Meteor.startup Meteor.subscribe.onReady...
please note below that blaze template helper gave undefined.
//client/main.js
Tracker.autorun(() => {
Meteor.subscribe('vehicles', {plate: Session.get('plate')});
});
Template.vehicle.helpers({
'vehicle' : function(){
let vehicle = Vehicles.findOne({'plate':Session.get('plate')})
console.log(vehicle) //prints undefined
}
})
Template.vehicle.events({
'keyup #plate'(e, inst){
let str = e.currentTarget.value
Session.set('plate', str)
console.log(str) // prints the value OK
}
})
The subscription will not be ready immediately. You need to first wait for the data to arrive at the client. Remember, everything on the client is asynchronous, as there are no Fibers in the browser (unlike on the server). This is why the subscribe
function has a onReady
callback you can specify:
Meteor.startup(function(){
Meteor.subscribe('vehicles', {onReady: () => {
console.log('subscription ready')
let rec = Vehicles.find({}).count()
console.log(rec)
}});
console.log('subscribed') // << this will print first
})
In practice you won't need this though, because you will usually use the data from a collection in a UI component, and there the UI framework (e.g., Blaze or React) will take take of the reactive re-rendering once data has arrived. In Blaze that is completely automatic, in React you will need to use useTracker
or withTracker
. Either way, the test you are running is still good to develop understanding of Meteor.
If you want to learn even more, open the developer console in your browser, go to Network, and watch the messages on the WS (web socket). You'll learn a lot about how DDP works, the protocol used by Meteor for synchronizing data between server and client. Knowing even just the basics of DDP can really help you build better Meteor applications and feel more confident with it.