In /lib/collections/task.js:
Tasks = new Mongo.Collection('tasks');
In server code:
Meteor.publish('tasks', function(){
return Tasks.find();
});
In client code:
Meteor.subscribe('tasks');
When I run this command Tasks.find().count()
The Browser console outputs 1, but the meteor:PRIMARY> db.Tasks.find().count()
reports 0.
I expected to see one records in both. Why it is not? Thanks
because it should be db.tasks.find().count()
not db.Tasks.find().count()
Per your declaration Tasks = new Mongo.Collection('tasks'); in Mongo, the collection is named 'tasks'
Related
I know that there are several methods to share collections on both the client and server -- namely either in top level lib folder or publish/subscribe model -- but when I try either of these things when using mongodb running at localhost:27017 as my MONGO_URL, I am not reliably getting data on the client. Occasionally console.log(myCollection.findOne({})) will return expected data in the browser but most of the time it returns undefined.
//Client side code
Template.controls.onCreated(function controlsOnCreated() {
Meteor.subscribe("myEvents");
Events = new Mongo.Collection("events");
});
//Server side code
Meteor.startup(() => {
Events = new Mongo.Collection("events");
}
Meteor.publish('myEvents', function() {
console.log(Events.find());
return Events.find();
});
UPDATED CODE -- returns Events on server but not client:
//Client
Template.controls.onCreated(function controlsOnCreated() {
this.subscribe("myEvents");
});
//Server
if (Meteor.isServer) {
Meteor.publish("myEvents", function() {
return Events.find();
});
}
// /collections/events.js
Events = new Mongo.Collection("events");
UPDATE 2:
I am attempting to verify the publication in the browser after the page has rendered, calling Events.findOne({}) in the Chrome dev tools console.
on your client:
Template.controls.onCreated(function controlsOnCreated() {
Meteor.subscribe("myEvents");
Events = new Mongo.Collection("events");
});
that is an odd place to define the Events variable. typically, you would put that line of code in a JS file common to both platform. e.g.
collections/events.js:
Events = new Mongo.Collection("events");
when that line runs on the server, it defines the mongo collection and creates a server-side reference to it. when it runs on the client, it creates a collection by that name in mini-mongo and creates a client-side reference to it.
you can write your onCreated like this (note "this" instead of "Meteor"):
Template.controls.onCreated(function() {
this.subscribe("myEvents");
});
you don't say where on the client you ran your console.log with the find(). if you did it in the onCreated(), that's too early. you're seeing the effects of a race condition. typically, you might use it in a helper:
Template.controls.helpers({
events() {
return Events.find({});
}
});
and display the data in the view:
{{#each event in events}}
{{event.name}}
{{/each}}
that helper will run reactively once the data from the publish shows up.
I am trying to create a Meteor app that stores content in a Meteor collection to be passed between the server and the client to display a success message after an asynchronous api call through the twit package.
However, I am running into an issue where when I update the collection on the server and the updates are not reflected on the client. My code is as follows:
/lib
Alerts = new Meteor.Collection("alerts");
/client
Template.suggestionForm.events({
"submit form": function (e) {
return Meteor.call('submitMessage', message);
}
});
Meteor.subscribe('alerts');
Meteor.startup(function() {
Tracker.autorun(function() {
console.log(Alerts.find());
})
});
/server
Fiber = Npm.require('fibers')
Twit = new TwitMaker({
consumer_key: '...',
consumer_secret: '...',
access_token: '...',
access_token_secret: '...'
});
Meteor.publish("alerts", function(){
Alerts.find();
});
Meteor.methods({
submitMessage: function(message) {
this.unblock();
Twit.post('statuses/update', { 'status': message }, function(err, data, response) {
Fiber(
Alerts.remove({});
Alerts.insert({response: err});
).run();
}));
}
});
When I submit the form the function calls just fine and updates the collection, however the Tracker.autorun() does not run. Any ideas why this is happening or how I can make the client listen for changes in collections would be super helpful. Thank you!
Remember to return the resulting cursor in the publish():
Meteor.publish("alerts", function(){
return Alerts.find();
});
Reference: http://docs.meteor.com/#/full/meteor_publish
Publish functions can return a Collection.Cursor, in which case Meteor will publish that cursor's documents to each subscribed client. You can also return an array of Collection.Cursors, in which case Meteor will publish all of the cursors.
and
Alternatively, a publish function can directly control its published record set by calling the functions added (to add a new document to the published record set), changed (to change or clear some fields on a document already in the published record set), and removed (to remove documents from the published record set). These methods are provided by this in your publish function.
If a publish function does not return a cursor or array of cursors, it is assumed to be using the low-level added/changed/removed interface, and it must also call ready once the initial record set is complete.
On the server side I want to publish only the data that concerns the current day.
This is my code on the server :
Meteor.publish('myData', function() {
var today = new Date();
today.setSeconds(0);
today.setMinutes(0);
today.setHours(0);
var tomorrow = new Date();
tomorrow.setSeconds(59);
tomorrow.setMinutes(59);
tomorrow.setHours(23);
return MyData.find({mTime : {$gt:today.getTime(), $lt:tomorrow.getTime()}});
});
The problem is that it seems this code is launched only when i deploy the app on the server.
So it is only getting the day of the deployment.
How can i get my app to republish the collection on accessing the app or on reload ?
Thanks
Try to place your subscribe code into Meteor.startup() function on the client side.
e.g.
if(Meteor.isClient){
Meteor.startup(function(){
Meteor.subscribe('myData');
});
}
This will re-subscribe the myData whenever the app is reloaded or refreshed.
Is it possible to test the Meteor client while the server is running using tinytest? Here's my example testing the client only:
Tinytest.add("Add object to a collection", function(test) {
var people = new Meteor.Collection("people");
people.insert({"name": "Andrew"}, function(error, id) {
test.isNull(error);
});
});
For a fraction of a second this passes, but then it goes into the state of "waiting". I'm also positive that error is not null.
Meteor.Error {error: 404, reason: "Method not found", details: undefined}
I know this is happening because their is no server for the client to communicate with. When I try to run this test on the server and client, I continue to get the same issue with the client. Is there a way to test the client while the server is running?
Thanks, Andrew
Use new Meteor.Collection with no argument to create a stub collection that doesn't require the server. See the docs on Collections:
If you pass null as the name, then you're creating a local collection. It's not synchronized anywhere; it's just a local scratchpad that supports Mongo-style find, insert, update, and remove operations.
This is an async test, so you'll have to use addAsync.
Tinytest.addAsync("Add object to a collection", function(test, next) {
var people = new Meteor.Collection("people");
people.insert({"name": "Andrew"}, function(error, id) {
test.isNull(error);
next();
});
});
Note the next argument which signals that you are done in the callback.
This is my first Meteor application, I'm really excited to try to learn the framework, so I just built an internal website that will manage a bunch of command line processes. Many of these command line processes take 10-20 minutes to execute, so I was hoping I could deliver feedback to the user during execution, such as piping the stdout back to the user as the process executed. Right now I'm doing this:
var require __meteor_bootstrap__.require
var sys = require('sys')
var exec = require('child_process').exec;
Meteor.methods({
foo: function(job_id) {
var select = { _id: job_id };
var execCommand = "dir /s"; // or whatever it is I'm doing
exec(execCommand, function(error, stdout, stderr) {
Fiber (function() {
Jobs.update(select, {$set: { logs: stdout }});
}).run();
})
}
});
This works fine, and when the job completes I see the log, but I was wondering if there was a better way I could do it so that as results are available I can start sending them. Any advise is welcome.
I would append the output line by line using the MongoDB $push operator instead of resetting the content of "logs" every time. That will save you some bandwidth I guess.
But apart from that, exec does not call your function regulary. Take a look at the "node.js execute system command synchronously question for a workaround.