Meteor Iron:Router Problems Getting ID - meteor

Can someone explain why am i getting the full value of ObjectID instead just the clean ID?
This is what i'm getting:
And the HTML output:
My Post
I haven't done anything out of the ordinary. Very basic stuff right now. Just trying out Meteor for the first time.
Routing: lib/router.js
// Dashboard
Router.route('/dashboard', {name: 'dashboard'});
// Post detail
Router.route('/summary/:_id', {
name: 'postSummary',
data: function() {
return Post.findOne(this.params._id);
}
});
List page template: templates/posts/post_dashboard.html
{{#each posts}}
<tr>
<td>
<p>{{title}}</p>
<p><small>Created at {{createdAt}}</small></p>
</td>
...
</tr>
{{/each}}
Detail page template: templates/posts/post_summary.html
<template name="postSummary">
{{> postHeader}}
<h3>{{title}}</h3>
</template>
Template helper: templates/posts/posts.js
Template.dashboard.helpers({
posts: function () {
return Post.find({});
}
});
And here's the packages i have installed, just in case it's necessary.
meteor-platform
autopublish
insecure
matthew:foundation5-sass
iron:router
jquery
useraccounts:core
useraccounts:foundation
accounts-password
accounts-facebook
accounts-google
accounts-ui-unstyled
aldeed:autoform
aldeed:collection2
forwarder:autoform-wizard
fortawesome:fontawesome

When you query the Posts collection from the console, is the _id in the returned document(s) a string literal or an ObjectId Object?
Assuming it's the latter, that's why this is happening, and if so, it's probably going to be because you've populated the collection by using insert in the Mongo shell (or alternatively restored from an existing MongoDB). By default, Meteor insert uses strings for the auto-added id when the id is not specified, whereas Mongo uses ObjectIds.
Hope that helps, but let me know if I'm on totally the wrong track!

Mongo ObjectID has a property: _str It includes string representation of the ID.

Related

Meteor not displaying data from collection in html

I am trying to get data from a collection in meteor and using a helper passing it to a template.
Here is my code in collection:
Meteor.publish('displayCustomers', function tasksPublication() {
return Customers.find();
});
Below code in template JS file
Template.customerlist.onCreated(function() {
Meteor.subscribe('displayCustomers');
});
Template.customerlist.helpers({
displayCustomers :function(){
console.log(Customers.find({}));
return Customers.find({});
},
});
Template:
<template name="customerlist">
<h1>All registered users</h1>
{{#each displayCustomers}}
{{fname}}
{{/each}}
</template>
It is only displaying HTML content i.e. <h1>All registered users</h1>
Check that your publication is returning values to the client with this MiniMongo chrome extension
Check to make sure Customers is defined on the server and that your publish block is running only on the server.
Also I would toss a debugger into your onCreated block to make sure that your subscribe is being initialized.
Other than that, your code looks fine. I would try installing MeteorToys Mongol for client pub/sub debugging. https://atmospherejs.com/msavin/mongol
You need to actually fetch documents in your template :
Template.customerlist.helpers({
displayCustomers :function(){
return Customers.find().fetch(); //will return an array with all published documents
},
});

Use Flow Router Param in Autoform

Friends,
I'm working on my first app in Meteor and hitting my head against the wall on something...
I have a scenario similar to a blog + comments situation where I have one collection (call it 'posts') and want to associate documents from another collection (call it 'comments').
The best way I know to pass the post._id to the comments as a "postId" field is to use the Flow Router params, since the form is on the 'post/:id' view.
But for the life of me, I cannot figure out how to get "var postId = FlowRouter.getParam('postId');" to pass to Autoform so it populates. I've tried adding it as a function in the schema, as a hook, and as a hidden field in the form on the page (obviously don't want to go that route).
Autoform is amazing and I want to use it, but may have to wire it up the hard way if I can't get this darn value to populate.
Any ideas? I've been hitting my head against the wall on this for a couple of days now.
Thanks!
First, just so we're on the same page, if you have your route is set up like this:
FlowRouter.route('/blog/:postId', {
action: function (params, queryParams) {
FlowLayout.render('layout', { body: 'postTemplate' });
},
});
You are able to call FlowRouter.getParam('postId') from inside the AutoForm hook
You'll need to use an AutoForm hook and have a complete schema. I'm using the package aldeed:collection2 for the schema set up. The postId field must be explicity declared. This code is running on both server and client.
Comments = new Mongo.Collection("comments");
Comments.attachSchema(new SimpleSchema({
comment: {
type: String,
label: "Comment"
},
postId: {
type: String
}
}));
Setting your form up like this is not what you want:
{{> quickForm collection="Comments" id="commentForm" type="insert"}}
That's no good because it will show the postId field in the HTML output. We don't want that, so you have to fully define the form like this:
{{#autoForm collection="Comments" id="commentForm" type="insert"}}
<fieldset>
{{> afQuickField name='comment' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
Then add the AutoForm hook. This code is running on the client.
var commentHooks = {
before: {
insert: function(doc){
var postId = FlowRouter.getParam('postId');
doc.postId = postId;
return doc;
}
}
};
AutoForm.addHooks(['commentForm'],commentHooks);
Make sure you have your allow/deny rules set up, and it should be working fine.
I was struggling with this same use case as well, and I found this on the Meteor forums: https://forums.meteor.com/t/use-flow-router-param-in-autoform/14433/2
If you're using a schema to build your form (either with the autoform or quickform tags) then you can put it right in there.
For example:
campaignId: {
type: String,
autoform: {
value: function() {
return FlowRouter.getParam('campaignId');
},
type: "hidden"
}
},

Meteor JS and State (address) select element

I want to have a state select in meteorjs for an address input field. I feel like listing out all the states in a massive html string of <option>s is wrong. Is there a documentation or preferred way to do this?
In frameworks like CakePHP, I would create a DB table related to address and just use the form helper methods to output the markup based on the table.
If you'd prefer to fetch a set of states from a database, you could create a Meteor Collection to store them.
States = new Mongo.Collection("states");
If you've removed the autopublish package (which if you haven't, you should), you need to then publish this collection,
if (Meteor.isServer) {
Meteor.publish("states", function() {
return States.find();
}
}
and then subscribe to it, and make it available to your template with a helper:
if (Meteor.isClient) {
Meteor.subscribe("states");
Template.myForm.helpers({
states: function() {
return States.find();
}
});
}
Then you can output the collection in your template as such:
<select>
{{#each states}}
<option>{{name}}</option>
{{/each}}
</select>
A nice way to enter the data into the database is through the Meteor Mongo shell or through a GUI like RoboMongo

Meteor Scope error when using Autoform

Using autoform and dependencies plus iron router. Autopublish is on and I'm seeing the collection on the client console. New project on .8, everything newly installed.
in schema.js, which I've tried in a few locations (/lib, /)
Tvseries = new Meteor.Collection("tvseries", {
schema: {
title: {
type: String,
label: "Title",
max: 250
},
airStartDate: {
type: Date,
label: "First episode air date"
}
}
});
Then a very basic autoform taken from the example:
<template name="addseries">
{{> quickForm collection="tvseries" id="inserttvseriesForm" type="insert"}}
</template>
Plus a route that is just loading this form:
Router.map(function () {
this.route('addseries', {
path: '/addseries',
template: "addseries"
});
});
I get this message in the JS console:
Exception from Deps recompute function: Error: tvseries is not in the window scope.
You have a typo:
<template name="addseries">
{{> quickForm collection="Tvseries" id="inserttvseriesForm" type="insert"}}
</template>
Your collection is named as Tvseries, not tvseries.
In case Serkan's typo suggestion didn't work, and for anyone looking for relief on this since this shows up on google and is how I got here:
From the docs (this section is buried too far down IMO)
Should the value of schema and collection have quotation marks around it?
If you use quotation marks, then you are telling the autoform to "look for an object in the window scope with this name". So if you define your collections at the top level of your client files and without the var keyword, then you can use this trick to avoid writing helpers.
If you don't use quotation marks, then you must define a helper function with that name and have it return the SimpleSchema or Mongo.Collection instance.
So you'd need a helper function that would look like this:
Template.addseries.helpers({
Tvseries: function () {
Return Tvseries;
}
});
And if you have a schema that is not attached to the collection, you'd also create another helper to return the schema so that you can call it from the template. The docs recommend registering this helper globally:
Template.registerHelper('Schemas', Schemas);

Handlebars + Meteor + iron-router

I am using iron-router for my meteor project and everything was going fine but I just ran into some strange behavior.
I have a loop set up for a list of items that looks something like this.
{{#each list_items}}
<div>{{user.username}}
Click here!
</div>
{{/each}}
The JSON object for my user looks something like this:
{
user: {
username: jdoe
},
images: {
low-res-url: http://example.com
},
link: http://example.com/profile
}
Now the {{user.username}} shows up as expected but when I try to put the {{link}} in the href I get an error from iron-router saying
"You called Router.path for a route named undefined but that that route doesn't seem to exist. Are you sure you created it?"
Any help or advice would be appreciated.
Under the hood Iron-Router registers handelbars helper:
Handlebars.registerHelper('link', function (options) {
...
});
Simply change field link to different name like my_link.
As #perhelium mentioned Iron-Router has specified a helper named 'link'
Handlebars.registerHelper('link', function (options) {...});
In order to access an item named 'link' in your JSON object you need to explicitly refer to the JSON object itself.
So your line: Click here!
Would need to be specified as Click here!

Resources