I am trying to use meteor-pages. In my JavaScript code I have:
Tasks = new Mongo.Collection("tasks");
Tasks.attachSchema(new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
complete: {
type: Boolean,
defaultValue: false,
label: " ",
autoform: {
type: "boolean-checkbox"
}
},
dueDate: {
type: Date,
label: "Due Date",
optional: true,
autoform: {
type: "pickadate"
}
}
}));
Pages = new Meteor.Pagination(Tasks, {
templateName: "tasksPaginated"
})
In my html, I have:
<template name="TaskList">
Before
{{> tasksPaginated}}
After
</template>
<template name="tasksPaginated">
{{> pages}}
{{> pagesNav}} Bottom navigation
</template>
When I try to browse to the page, I get the following error:
Exception in delivering result of invoking 'pages_tasks/CountPages':
Error
at Connection._livedata_result (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4736:23)
at onMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3385:12)
at http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2736:11
at Array.forEach (native)
at Function..each..forEach (http://localhost:3000/packages/underscore.js?hash=cde485f60699ff9aced3305f70189e39c665183c:149:11)
at SockJS.self.socket.onmessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2735:11)
at SockJS.REventTarget.dispatchEvent (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:175:22)
at SockJS._dispatchMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1160:10)
at SockJS._didMessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1218:18)
at WebSocket.that.ws.onmessage (http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1365:17)
Any ideas what I could be doing wrong?
The documentation for meteor-pages says you can initialise it like this:
this.Pages = new Meteor.Pagination("tasks");
And this will automatically pick up a template called "tasks". The other way (which I think you want) is to specify a different template, in which case your code should be :
this.Pages = new Meteor.Pagination("tasks", {itemTemplate: "tasksPaginated"});
That should solve it for you
Make sure the code
Pages = new Meteor.Pagination(Tasks, {
templateName: "tasksPaginated"
})
don't run before your Template.tasksPaginated is available globally
Related
I am new in meteor. I am using simple schema for quickForm and got this error.
Exception in template helper: TypeError: Cannot read property 'mergedSchema' of undefined
main.html
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
{{> quickForm collection="Books" id="bookUpdateForm" type="insert"}}
</template>
main.js
import './hello.html';
import { Books } from '../../../api/links/books.js';
Template.hello.onCreated(function () {
Meteor.subscribe('books');
});
Collection JS
import SimpleSchema from 'simpl-schema';
export const Books = new Mongo.Collection("books");
const Book = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
author: {
type: String,
label: "Author"
},
copies: {
type: SimpleSchema.Integer,
label: "Number of copies",
min: 0
},
lastCheckedOut: {
type: Date,
label: "Last date this book was checked out",
optional: true
},
summary: {
type: String,
label: "Brief summary",
optional: true,
max: 1000
}
});
Books.attachSchema(Book);
There is a typo that causes a follow up error. You collection is namen "books" but you pass "Books" to your quickForm. Because AutoForm cannot find any collection named "Books" in global scope it will throw an error.
This approach also assumes Books to be in window scope.
If you are new to JS, then you may first read about scopes and window scope:
https://developer.mozilla.org/en-US/docs/Glossary/Scope
https://developer.mozilla.org/en-US/docs/Web/API/Window
Why are global variables considered bad practice?
Less error prone pattern
An alternative approach would be to import Books to your template (as you have already done) and provide it to quickForm via a Template helper:
main.html
<template name="hello">
{{> quickForm collection=getCollection id="bookUpdateForm" type="insert"}}
</template>
Note getCollection which is basically calling a helper you define in your Template helpers section:
main.js
import './hello.html';
import { Books } from '../../../api/links/books.js';
Template.hello.onCreated(function () {
Meteor.subscribe('books');
});
Template.hello.helpers({
getCollection() {
return Books;
}
});
By doing so you have a) avoided window (global) scope and b) avoided errors due to spelling errors, because you pass the reference to the collection directly to the quickForm.
Collection JS
import SimpleSchema from 'simpl-schema';
export const Books = new Mongo.Collection("books");
const Book = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
author: {
type: String,
label: "Author"
},
copies: {
type: SimpleSchema.Integer,
label: "Number of copies",
min: 0
},
lastCheckedOut: {
type: Date,
label: "Last date this book was checked out",
optional: true
},
summary: {
type: String,
label: "Brief summary",
optional: true,
max: 1000
}
});
Books.attachSchema(Book);
I created two seperate schemas for payments collection and memberProfile. Now I need to create a quickform so I could load all the payments relevant to a unique memberProfile.
//The code for memberPayment collection
MemberProfiles = new Mongo.Collection('memberProfiles');
RecipeSchema = new SimpleSchema({
name: {
type: String,
label: "Name"
},
desc: {
type: String,
label: "Description"
},
payments:{
type: [PaymentSchema],
autoValue: function () {
return Payments.find({ memberId="uniqueId"});
},
defaultValue: function () {
return Payments.find({memberId="uniqueId"});
},
},
// The code for payments collection
PaymentSchema = new SimpleSchema({
name:{
type: String
},
amount:{
type: String
},
memberId:{
type: String
},
});
This code doesn't work.
Looks like you're missing the schema attribute. Any autoform needs to take in a schema attribute that explicitly tells autoform to use that schema to generate the necessary form. Check this page out for demos using autoform.
{{> quickForm collection="theMongoCollection" id="theFormID" schema="theSchemaName" type="typeOfForm" }}
I'm trying to build an update form for a document that has a select-multiple field in the Schema
I use quickForm
I have this on the schema side for the drop down:
channels: {
type: [String],
label: "Channels",
optional: false,
autoform: {
type: "select-multiple",
options: function () {
var dc = Channels.find({}).fetch();
return dc.map(function (channel) { return {label: channel.name, value: channel._id}});
}
}
}
on the form side, I pass the doc
{{> quickForm
collection="Blah"
id="updateChannels"
type="method-update"
meteormethod="updateBlah"
doc=this
}}
I get the fields from the document, but the select-multiple shows the list of options, without selected items.
How do I get the selected items to show selected in that list?
Using SimpleSchema in Meteor with the AutoForm + Select2 plugins , i am trying to generate the Options for a Select field from the database.
The 'occupation' collection is published, and a collection 'Occupation' is defined in Meteor.
In SimpleSchema I have this:-
occupations: {
type: [String],
optional:true,
label: 'Occupation',
autoform:{
type:"select2",
placeholder: 'Comma spaced list of occupations',
options: function () {
Meteor.subscribe('occupations');
return Occupations.find({});
}
}
},
But it does not return the collection results, and crashes the application without an error message.
It seems the best way to handle this is to supply the options list through a helper.
{{> afQuickField name='occupations' multiple=true tags=true options=listOccupations}}
Where listOccupations is a helper within the template containing the form.
Template.myForm.helpers({
listOccupations: function () {
Meteor.subscribe('occupations');
return Occupations.find({}).fetch();
}
});
And we remove the options object from the schena
occupations: {
type: [String],
optional:true,
label: 'Occupation',
autoform:{
type:"select2",
placeholder: 'Comma spaced list of occupations',
}
},
Have you tried, this approach:
autoform: {
options: {
var occupations = [];
Occupations.find().map(function(occ) {
occupations.push(
{label: occ.description, value: occ._id}
);
});
return occupations;
}
}
hope this helps..
I had the same issue. I'm defining my collections schema in /lib/collections folder, and that is running on both server and client side. Given that, the console.log that I had was printing the correct values on server side and an empty array on client side.
What I did was:
if (Meteor.isClient){
Meteor.subscribe('service-categories-list', {
onReady: function(){
const serviceCategories = ServiceCategories.find({}).map(function(item, index) {
return {
label: item.name,
value: item.slug
};
});
Schema2._schema.type.autoform.options = serviceCategories;
}
})
}
I know that using the _schema is not a good idea, but I accept suggestions :)
How do send custom validation message to another schema field ?
SessionSchema = new SimpleSchema({
'seat.from': {
type: String,
max: 10,
optional: false
},
'seat.to': {
type: String,
max: 10,
optional: false
}
});
ReservationSchema = new SimpleSchema({
title: {
type: String
},
sessions: {
type: [SessionSchema],
min: 1,
optional: false,
custom: function() {
//Its an array object. validation is depends on next array so I made a validation here instead of `SessionSchema`.
return "greater-session"; // dispaly error on top of the session. I need to display error message on perticular field in `SessionSchema`.
}
}
});
SimpleSchema.messages({
"greater-session": "From seat should not lesser then previous session"
});
Autoform:
{{#autoForm id="addReservation" type="method" meteormethod="insertMyReservation" collection="Reservation"}}
{{> afQuickField name="title" autofocus=''}}
{{> afQuickField name="sessions" panelClass="group"}}
{{/autoForm}}
How do I achieve this?
I would suggest you using a custom validator for your SimpleSchema. They have access to more context information.
I would try something like this:
ReservationSchema = new SimpleSchema({
title: {
type: String
},
sessions: {
type: [SessionSchema],
min: 1,
optional: false,
custom: function() {
var sessions = this.value; // array;
var seatTo = 0; // initalize # 0
var hasError;
// loop through seach session
_.each(sessions, function(s, index) {
// if seatFrom < previous seatTo
if (s['seat.from'] < seatTo) {
hasError = true;
};
seatTo = s['seat.to']; // update seatTo for next iteration
});
if (hasError) {
return "greater-session"; // dispaly error on top of the session. I need to display error message on perticular field in `SessionSchema`.
}
}
}
});