I defined the collection in lib/collection.js
var Tags = new Meteor.Collection("Tags");
Then trying to initialize it in server/main.js:
Tags.insert({name: tag["tag"], default_show: true});
Got error:
W20141028-01:26:53.647(11)? (STDERR) ReferenceError: Tags is not defined
W20141028-01:26:53.648(11)? (STDERR) at app/server/main.js:43:18
I cannot figure out why I got error here? Anyone could give me some hints?
Full source code:
server/main.js
Meteor.startup(function() {
var tagsJson = JSON.parse(Assets.getText("tags.json"));
var tagsMapJson = JSON.parse(Assets.getText("tags_map.json"));
tagsJson["lines"].map(function(line) {
line["tags"].map(function(tag){
if (!Tags.findOne({name: tag["tag"]})) {
Tags.insert({name: tag["tag"], default_show: true});
}
tagsMapJson[tag["tag"]].map(function(web) {
if (!Webs.findOne({url: web["url"]})) {
Webs.insert({url: web["url"], name: web["name"], brief: web["brief"]});
}
if (!TagWebs.findOne({tag: tag["tag"], url: web["url"]})) {
TagWebs.insert({tag: tag["tag"], url: web["url"]});
}
});
});
});
});
lib/collections.js
var Tags = new Meteor.Collection("Tags");
var Webs = new Meteor.Collection("Webs");
var TagWebs = new Meteor.Collection("TagWebs");
I think you should erase "var" so collection is seen to whole project
Related
I developed a meteor app in which while registering I am fetching the user location at the client side, to do so I have added the packages listed below:
meteor add mdg:geolocation
meteor add jeremy:geocomplete
meteor aldeed:geocoder
meteor add jaymc:google-reverse-geocode
The code written at client side is as follows:
if (Meteor.isClient) {
Meteor.startup(() => {
GoogleMaps.load({
v: '3.26',
key: '',
libraries: 'geometry,places'
});
console.log("is GoogleMaps.loaded",GooglMaps.loaded());
});
Template.Registration.onRendered(function () {
Tracker.autorun(() => {
if (GoogleMaps.loaded()) {
$('#txt_address').geocomplete({country: "AU", type:
['()']});
}
});
var date = new Date();
$('#div_dob').datetimepicker({
format: 'DD/MM/YYYY',
maxDate : date,
ignoreReadonly: true
});
date=null;
});
Template.Registration.helpers({
location:function(){
$('input[name="txt_address"]').val(Session.get('location'));
}
});
Template.Registration.events({
'click #btn_findlocation':function(event){
alert('Find Location')
event.preventDefault();
function success(position) {
var crd = position.coords;
console.log(`Latitude0 : ${crd.latitude}`);
console.log(`Longitude0: ${crd.longitude}`);
var lat = crd.latitude;
var long = crd.longitude;
reverseGeocode.getLocation(lat, long, function(location)
{
console.log("Address",JSON.stringify(reverseGeocode.getAddrStr()));
Session.set('location', reverseGeocode.getAddrStr());
});
};// end of function success(position)
function error(err) {
console.warn('ERROR(' + err.code + '): ' + err.message);
};//end of function error(err)
// geolocation options
var options = {
enableHighAccuracy: true,
maximumAge: 0
};// end of var options
navigator.geolocation.getCurrentPosition(success, error,
options);
},
})
}
But I am getting false value for GoogleMaps.loaded() function and the following below error when I click a button to fetch the location.
Can't able to read formatted address of undefined.
Results are inconsistent as sometimes I was able to fetch the location other times not.
Please give any suggestions...
I'm trying to publish some data using meteorhacks:aggregate:
Meteor.publish('alleNascholingen',function() {
var self = this;
var nascholingenOverzicht = nascholingenCollectie.aggregate([
//{$match: {creatorId: this.userId}},
//{$project: {naam: 1, familienaam:1, nascholingen:1}},
{ $unwind : "$nascholingen" },
{ $sort: {
"nascholingen.inschrijfMoment": -1
}}
]);
_.each(nascholingenOverzicht, function(parent){
_.each(parent, function(child){
self.added('selectie', child._id, child);
});
});
self.ready()
});
I have two collections, one to store the aggregated data:
nascholingenCollectie = new Mongo.Collection('nascholingen');
nascholingenSelectie = new Mongo.Collection('selectie');
On my template I subscribe to the data:
Template.nascholingBeheer.onCreated(function() {
let self = Template.instance();
self.subscribe('alleNascholingen', function () {
setTimeout(function () {
}, 300)
})
})
});
I'm getting the following error in my chrome console:
collection.js:173 Uncaught Error: Expected to find a document to change
at Object.update (http://localhost:3000/packages/mongo.js?hash=c4281c0ff989ebee020f59f5a7b0735053cea5f7:246:29)
at Object.store.(anonymous function) [as update] (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3613:48)
at http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4441:19
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?hash=cde485f60699ff9aced3305f70189e39c665183c:149:11)
at http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4440:13
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?hash=cde485f60699ff9aced3305f70189e39c665183c:157:22)
at Connection._performWrites (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4437:9)
at Connection._flushBufferedWrites (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4423:10)
at Connection._livedata_data (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4391:12)
What am I doing wrong here?
You can not use aggregation in Meteor publication, only in Meteor method. To work around that you could consider using this package (disclaimer: I am the author).
My bad...I found my error:
_.each(nascholingenOverzicht, function(parent){
_.each(parent, function(child){
self.added('selectie', child._id, child);
});
});
should be:
_.each(nascholingenOverzicht, function(parent){
self.added('selectie', parent._id, parent);
});
Model code:
ProfileImage = new FS.Collection('profileImage', {
stores: [
new FS.Store.FileSystem('profile-image')
],
filter: {
maxSize: 524288,
allow: {
extensions: ['png', 'jpg', 'jpeg'],
contentTypes: ['image/png', 'image/jpg', 'image/jpeg']
}
}
});
Insertion code:
ProfileImage.insert('http://graph.facebook.com/' + user.services.facebook.id + '/picture/?type=large', function(error, imageObj) {
console.log(imageObj);
});
with that code I get a file name like this: profileImage-iiGE2ouSifuu3iLjq-undefined .
the name is undefined and without extension at all.
Try this (copied from a project of mine. this works):
//this is the event for when you select an image
'change .yourfileinput': function (event, template) {
FS.Utility.eachFile(event, function (file) {
var yourFile = new FS.File(file);
Images.insert(yourFile, function (err, fileObj) {
var fileUrl = '/cfs/files/profile-image/'+fileObj._id;
Session.set('fileUrl', fileUrl);
});
});
},
//form submit event
"submit .your-form-class": function (event) {
var whichUser = Meteor.userId() //or you could just write this inside the method call instead of adding a variable
var profilePicture = Session.get('fileUrl');
Meteor.call("yourMethod", whichUser, profilePicture);
}
Of course, you need to play on it/customise to your needs. ^ is for default file path of cfs:filesystem.
I switched to gridfs though and I highly recommend it.
Edit your question with all your code if it doesn't work and we'll find a solution. File upload was the biggest problem I encountered along the way.
I am experimenting with meteor and I'm facing some code structuring issue.
What I want:
I use an observer to keep track of new document added on collection, but i want to be 'notified' only after the the template is fully rendered.
In my router.js file i have:
HospitalListController = RouteController.extend({
action: function() {
Meteor.subscribe('hospitals');
this.render('listHospitals');
}
});
My client listHospital.js file is
Template.listHospitals.onRendered(function(){
var first = true;
hospitalsCursor = Hospitals.find();
var totals = hospitalsCursor.count();
var loaded = 0;
HospitalsHandle = hospitalsCursor.observeChanges({
added : function(doc){
if( loaded != totals ){
loaded++;
}else{
console.log("added "+doc);
}
}
});
});
Is there a better way, maybe a 'meteor-way' to accomplish that?
You have to add a flag to ignore observeChange callback during initialization (found this solution here).
Template.listHospitals.onRendered(function(){
var initialized = false;
hospitalsCursor = Hospitals.find();
HospitalsHandle = hospitalsCursor.observeChanges({
added : function(doc){
if(initialized) {
// your logic
}
}
});
initialized = true;
});
This should work.
My actual working code:
Template.queueView.onRendered(function(){
var initialLoaded = false;
Queues.find().observeChanges({
added : function(id, doc){
if( initialLoaded ){
console.log("added "+id);
highlight();
beep();
}
},
removed : function(id, doc){
console.log("removed "+id);
highlight();
beep();
},
changed : function(){
console.log('modified!');
highlight();
beep();
}
});
Meteor.subscribe('queues', function(){
initialLoaded = true;
});
});
I have a problem with my Meteor's JS file. I get this error "insert failed: Method not found" when I try to insert any data to the database and reflect on chart. I've tried fetching data directly from db that didn't work too...
thanx in advance.
LinePeople = new Mongo.Collection("LinePeople");
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
if (Meteor.isClient) {
console.log("in LIne Client");
//LinePeople = new Mongo.Collection(null);
Template.linenvd3.rendered = function() {
var chart = nv.models.lineChart()
.margin({left: 80}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
nv.addGraph(function() {
chart.xAxis.axisLabel('Person number').tickFormat(d3.format('d'));
chart.yAxis.axisLabel('Age (years)').tickFormat(d3.format('d'));
d3.select('#lineChart svg').datum(
[{ values: LinePeople.find().fetch(), key: 'Age' }]
).call(chart);
nv.utils.windowResize(function() { chart.update() });
return chart;
});
Deps.autorun(function () {
d3.select('#lineChart svg').datum(
[{ values: LinePeople.find().fetch(), key: 'Age' }]
).call(chart);
chart.update();
});
};
Template.linenvd3.events({
'click #addDataButton': function() {
console.log(" in line addButton");
var age = getRandomInt(13, 89);
var lastPerson = LinePeople.findOne({}, {fields:{x:1},sort:{x:-1},limit:1,reactive:false});
if (lastPerson) {
console.log(" in lastPerson.. if block");
LinePeople.insert({x:(lastPerson.x + 1), y:age});
} else {
console.log(" in lastPerson.. else block");
LinePeople.insert({x:1, y:age});
}
},
'click #removeDataButton': function() {
console.log(" in line removeButton");
var lastPerson = LinePeople.findOne({}, {fields:{x:1},sort:{x:-1},limit:1,reactive:false});
if (lastPerson) {
LinePeople.remove(lastPerson._id);
}
}
});
}
if (Meteor.isServer) {
console.log("in line Server");
}
While following the Getting Started tutorial on the official meteor.js website I've had the same problem with autopublish turned on.
Turned out the issue was I created my Tasks collection inside the imports/ folder. Thus it was not implicitly imported on the server.
I had to explicitly import it on the server to solve the issue.
server/main.js
import { Meteor } from 'meteor/meteor';
import '../imports/api/tasks.js';
Meteor.startup(() => {
// code to run on server at startup
});
As you can see the import is not used by my code but is required anyways.
Thanks for the help... I actually got it worked by publishing the collection and giving it some permissions:
This code is placed in "myapp/shared/collections.js". (Placed them separately to handle all the other collections which I would add for other graphs)
lineVar = new Meteor.Collection("linenvd3");
lineVar.allow({
insert: function () {
return true;
},
update: function () {
return true;
},
remove: function () {
return true;
}
});
This code is placed in "myapp/server/publish.js"
Meteor.publish('line', function () {
return lineVar.find();
});
Then, this is modified Javascript made look more simpler and comprehensive.
if (Meteor.isClient) {
Meteor.subscribe('line');
Template.linenvd3.rendered = function() {
var chart = nv.models.lineChart()
.margin({left: 80})
.useInteractiveGuideline(true)
.transitionDuration(350)
.showLegend(true)
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
nv.addGraph(function() {
chart.xAxis.axisLabel('Person number').tickFormat(d3.format('d'));
chart.yAxis.axisLabel('Age (years)').tickFormat(d3.format('d'));
d3.select('#lineChart svg').datum(
[{ values: lineVar.find().fetch(), key: 'Age' }]
).call(chart);
nv.utils.windowResize(function() { chart.update() });
return chart;
});
Deps.autorun(function () {
d3.select('#lineChart svg').datum(
[{ values: lineVar.find().fetch(), key: 'Age' }]).call(chart);
chart.update();
});
};
}