I keep on getting these error messages in my browser console:
Exception in template helper: ReferenceError: "CollectionNames" is not defined
The "CollectionNames" being all the collections I have in my app. I have researched but cant find a suitable solution.
My environment: I am running meteor 1.2
The task.js file is where I define each collection. Below is the code in task.js
/myMeteorApp
--/imports/api/tasks.js
import { Mongo } from "meteor/mongo";
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})] });
buyList = new Mongo.Collection("BuyList");
WhoAreWe = new Mongo.Collection("whoDb");
merchantReviews = new Mongo.Collection("merchantReviews");
Messages = new Meteor.Collection("messages", {transform: function (doc)
{ doc.buyListObj = buyList.find({sessionIDz: {$in: [doc.buyList]}}); return doc; }});
The server is where I publish the collections. Below is the code:
/myMeteorApp
--/server/main.js
import buyList from '../imports/api/tasks.js';
import Messages from '../imports/api/tasks.js';
import Images from '../imports/api/tasks.js';
import WhoAreWe from '../imports/api/tasks.js';
import merchantReviews from '../imports/api/tasks.js';
Meteor.startup(() => {
// code to run on server at startup
Meteor.publish('buyList', function(){
return buyList.find();
});
Meteor.publish('Messages', function(){
return Messages.find();
});
Meteor.publish('Images', function(){
return Messages.find();
});
Meteor.publish('WhoAreWe', function(){
return WhoAreWe.find();
});
Meteor.publish('merchantReviews', function(){
return merchantReviews.find();
});
});
And the client is where I subscribe for the collections. Find below the code:
/myMeteorApp
--/client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Meteor.subscribe('Messages');
Meteor.subscribe('WhoAreWe');
Meteor.subscribe('Images');
Meteor.subscribe('buyList');
Where am I going wrong. I've been at this for many days now... Kindly help!
The collections must be defined on both the client and the server! Just import your collection names on the client side as well as the server:
import { buyList, Messages, Images, WhoAreWe, merchantReviews } from '../imports/api/tasks.js';
You still have to subscribe to the various publications of course.
It is a naming problem, when you publish the collection, you should refer to the collection name (messages), not the meteor variable (Messages)
Meteor.publish('messages', function(){...
Related
I read similar questions but could not find one with publish/subscribe to match.
The browser failed to see the collection contactsCol, why and how fo fix it? Thanks
// imports/api/contacts.js
import {Mongo} from 'meteor/mongo';
export const ContactsCol = new Mongo.Collection('contactsCol');
///server/publication.js
import {ContactsCol} from '../imports/api/contacts.js';
Meteor.publish('contactsCol', function () {
if (!this.userId) return;
if (this.userId && Meteor.users.findOne({_id:this.userId}).profile.carsInfoMenu.indexOf('a') != -1){
console.log('contactsCol retured documents');
return ContactsCol.find();
}
return;
});
// client/main.js
Template.body.onCreated(function () {
Meteor.subscribe('contactsCol');
});
Template.input.helpers({
'listData': function (searchFor){
return contactsCol.find().fetch(); //<<<< this line is causing the error
}
});
Update of what I tried for no avail:
Added the following to main/client.js
`import {contactsCol} from "../imports/api/contacts.js";
Template.body.onCreated(function () {
Meteor.subscribe('contactsCol');
Template.input.helpers({
'listData': function (searchFor){ //17c
return contactsCol.find().fetch();
}
}
Solved:
I removed the subscription line from client/main.js
Template.body.onCreated(function () {
// Meteor.subscribe('contactsCol');
Added this import statement to the top of the file
import {ContactsCol} from "../imports/api/contacts.js";
And in the helper method I used:
return ContactsCol.find().fetch();
why is it working fine now with out subscription? I have no idea. would be great if some one can explain. thx
You need to import the collection on the client as well. Right now it's an undefined variable.
// client/main.js
import { ContactsCol } from '../imports/api/contacts.js';
Template.body.onCreated(function () {
Meteor.subscribe('contactsCol');
});
Template.input.helpers({
'listData': function (searchFor){
return ContactsCol.find().fetch(); //<<<< this line is causing the error
}
});
The subscription only loads the data from the server to the client. The client still needs to define the collection to store those documents in and access them from. Importing the collection provides this
EDIT: Missed the capitalization of the module export
So I have a master/detail scenario between two views. The master page shows a list and after clicking on one of the items, I send a message via the EventAggregator in Aurelia to the child view with a deserialized dto (coming from the selected item of the master) as a payload of the message.
However when I then try to pass this item as a parameter of a subsequent request in the child (to get additional info) the payload object fails to serialize.
Master.ts:
import { JsonServiceClient } from "servicestack-client";
import {
ListPendingHoldingsFiles,
ListPendingHoldingsFilesResponse,
SendHoldings,
PositionFileInfo
} from "../holdingsManager.dtos";
import { inject, singleton } from "aurelia-framework";
import { Router } from "aurelia-router";
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
#singleton()
#inject(Router, EventAggregator)
export class Pending {
router: Router;
positions: PositionFileInfo[];
client: JsonServiceClient;
eventAgg: EventAggregator;
constructor(router, eventAggregator) {
this.router = router;
this.eventAgg = eventAggregator;
this.client = new JsonServiceClient('/');
var req = new ListPendingHoldingsFiles();
this.client.get(req).then((getHoldingsResponse) => {
this.positions = getHoldingsResponse.PositionFiles;
}).catch(e => {
console.log(e); // "oh, no!"
});
}
openHoldings(positionInfo) {
this.eventAgg.publish(new GetPendingPositionMessage(positionInfo));
this.router.navigate('#/holdings');
}
}
Child.ts:
import { JsonServiceClient } from "servicestack-client";
import { inject, singleton } from "aurelia-framework";
import { Router } from 'aurelia-router';
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
import {
GetPendingHoldingsFile,
GetPendingHoldingsFileResponse,
Position,
PositionFileInfo
} from "../holdingsManager.dtos";
#singleton()
#inject(Router, EventAggregator)
export class Holdings {
router: Router;
pendingPositionFileInfo: PositionFileInfo;
position: Position;
client: JsonServiceClient;
eventAgg: EventAggregator;
constructor(router, eventAggregator) {
this.router = router;
this.eventAgg = eventAggregator;
this.eventAgg.subscribe(GetPendingPositionMessage,
message => {
this.pendingPositionFileInfo = message.fileInfo;
});
}
activate(params, routeData) {
this.client = new JsonServiceClient('/');
var req = new GetPendingHoldingsFile();
req.PositionToRetrieve = this.pendingPositionFileInfo;
this.client.get(req).then((getHoldingsResponse) => {
this.position = getHoldingsResponse.PendingPosition;
}).catch(e => {
console.log(e); // "oh, no!"
});
}
}
So the error happens when the child activates and attempts to send the request 'GetPendingHoldingsFile'.
Failed to load resource: the server responded with a status of 500 (NullReferenceException)
I have verified that this.pendingPositionFileInfo in the child is not null or empty and that on the server side, the object is not being received (it is null). I am new to Aurelia and not very experienced with Javascript so I must be missing something, any advice would be appreciated.
Edit 1
This seems to be something wrong with how I'm interacting with ServiceStack. I'm using version 4.5.6 of serviceStack with servicestack-client#^0.0.17. I tried newing up a fresh copy of the dto (PositionFileInfo) and copying over all the values from the parent view just to be sure there wasn't some javascript type conversion weirdness happening that I'm not aware of, but even with a fresh dto the webservice still receives a null request.
Switching from 'client.get(...)' to 'client.post(...)' fixed the problem. Apparently trying to serialize the object over in the URL was not a good plan.
My app was working perfectly till I externalized the collection definition from the client/main.js file to the ../imports/api/tasks.js file.
After this move I keep getting this error message in my browser: Uncaught TypeError: Cannot read property 'insert' of undefinedin my browser console. This error message points to line main.js:1206 which is:
/myApp
../client/main.js
import { Images } from '../imports/api/tasks.js';
Meteor.subscribe('Images');
FS.Utility.eachFile(event, function(file) {
var teste = Images.insert(file, function (err, fileObj) {
var insertedIdSession = teste._id;
session.set("insertedBuyId", insertedIdSession);
Images.find().count());
});
/myApp
../imports/api/tasks.js
import { Mongo } from "meteor/mongo";
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})] });
/myApp
../server/main.js
import { Images } from '../imports/api/tasks.js';
Meteor.publish('Images', function(){
return Images.find();
});
I have researched but failed to find a solution for this. Kind point out where i am going wrong.
It is telling you that "Images" is not defined.
From what I can see of your code, ../imports/api/tasks.js does not export anything, which means that
import { Images } from '../imports/api/tasks.js';
won't give you anything, in fact it will replace the global variable Images with a null. So I think the solution is to replace the imports with this:
import '../imports/api/tasks.js';
Or you can put tasks.js in /common and that will do the same job
You need to export your Images collection in order to import it to other files, like this:
import { Mongo } from "meteor/mongo";
export const Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})]
});
I'm learning how to use meteor and I'm having trouble syncing the clients collection with what the server has. I'm trying to make a counter that increments by one every time you click it by calling a method on the server. When I go to my application it always displays 1 but when I do .find() on my collection through the Mongo shell it has what the number should actually be. I have autopublish on so shouldn't this work automatically? Here is my code for both client and server:
/client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Counter= new Mongo.Collection('counter');
Template.counter.helpers({
counter() {
return Counter.find({});}
});
Template.counter.events({
'click #a':function() {
Meteor.call('add')
},
});
/client/main.html
<head>
<title>HypeCoins</title>
</head>
<body>
<h1>HypeCoins</h1>
{{> counter}}
</body>
<template name="counter">
<button id='a'>Click Me</button>
<p>You've pressed the button {{counter.count}} times.</p>
</template>
/server/main.js
import { Meteor } from 'meteor/meteor';
Counter= new Mongo.Collection('counter');
Meteor.startup(() => {
});
Meteor.methods({
'add':function(){
Counter.update({},{$inc:{count:1}});
}
});
You will get your solution by using a modifier on your update. This will require you to create an ID so there is something to update. You can do so by:
client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Counter = new Mongo.Collection('counter');
Template.counter.helpers({
counter() {
return Counter.findOne();
}
});
Template.counter.events({
'click #a':function() {
Meteor.call('add');
},
});
server/main.js
import { Meteor } from 'meteor/meteor';
Counter = new Mongo.Collection('counter');
Meteor.methods({
'add': function() {
currentCount = Counter.findOne();
if (!currentCount) {
Counter.insert({ count: 1});
}
Counter.update({_id: currentCount._id }, { $inc: { count: 1 } });
},
});
Refer to Meteor documentation:
https://docs.meteor.com/api/collections.html#Mongo-Collection-update
You have to define your collection schema. Take a look at that package it should be useful for you: https://github.com/aldeed/meteor-simple-schema
I'm struggling to understand Meteor 1.3's include logic.
For an app I'm trying to put together, I have in /client/main.js:
import '../imports/startup/accounts-config.js';
import '../imports/ui/body.js';
import '../imports/ui/home.js';
import '../imports/ui/map.js';
import '../imports/ui/admin.js';
...
In /imports/ui/body.js, I have (I use flow router and mainLayout is the main layout, in which all other templates are rendered):
...
Template.mainLayout.onCreated(function mainLayoutOnCreated() {
Meteor.subscribe('tasks');
Meteor.subscribe('categories');
});
...
Then I have the following function:
Template.admin.helpers({
categories() {
return Categories.find({}, { sort: { createdAt: -1 } });
},
});
If I put this function in /imports/ui/body.js, I'm able to call 'categories' in the template with name 'admin'. However, when I put this function in /imports/ui/admin.js, I get a useless exception in the javascript console:
Exception in template helper: categories#http://localho...
How is it that moving the file in which this helper is declared, while still being included in the same 'main' file, results in an exception being thrown?
You should import the desired template and the templating package at the top of your admin.js file.
import {
Template
} from 'meteor/templating';
import '.deep/admin.js';
Template.admin.helpers({
categories() {
return Categories.find({}, { sort: { createdAt: -1 } });
},
});