Meteor: Iterating over mongoDB collection produces no results - mongodb

I have a collection in Mongo that is populated with three records.
When viewing my app in localhost, it lists nothing. There are no errors displayed, however nothing is listed either.
What am I doing wrong?
Console output from manual find:
meteor:PRIMARY> db.users.find({})
{ "_id" : ObjectId("55ddba705374fcb03117d585"), "username" : "coderboy", "joined" : ISODate("2015-08-26T13:09:04.872Z") }
{ "_id" : ObjectId("55ddc7475374fcb03117d586"), "username" : "plumberboy", "joined" : ISODate("2015-08-26T14:03:51.960Z") }
{ "_id" : ObjectId("55ddcf3b5374fcb03117d587"), "username" : "sparkieboy", "joined" : ISODate("2015-08-26T14:37:47.883Z") }
HTML:
<body>
<div class="container">
<h2>Our users:</h2>
<ul>
{{#each user}}
{{> userlist}}
{{/each}}
</ul>
</div>
</body>
<template name="userlist">
<li>{{username}}</li>
</template>
JS:
users = new Mongo.Collection("users");
if (Meteor.isClient) {
Template.userlist.helpers({
user: function () {
return users.find({});
}
});
}

You use the user helper of userlist outside of the userlist template. So that's not defined. An easy fix is put move the each into the userlist template.
<body>
<div class="container">
<h2>Our users:</h2>
<ul>
{{> userlist}}
</ul>
</div>
</body>
<template name="userlist">
{{#each user}}
<li>{{username}}</li>
{{/each}}
</template>

Related

Meteor: Can't display my collections

I have a collection named by "btso". I just tried to display this collection from this database but it doesn't display. I don't know if i have any errors in my code.
Here is main.html
<head>
<title>Sanji</title>
</head>
<body>
<div class="container">
<h4>Sanji's first meteor app</h4>
<ul class="collection">
{{> sanji}}
</ul>
</div>
</body>
<template name="sanji">
{{#each btso}}
<li class="collection-item">{{text}}</li>a
{{/each}}
</template>
Here is my main lib/collections.js
import { Mongo } from 'meteor/mongo';
export const Btso = new Mongo.Collection('btso');
And here is my main.js
import { Template } from 'meteor/templating';
import { Btso } from '../lib/collections.js';
import './main.html';
Template.sanji.helpers({
btso: function(){
return Btso.find({});
}
});

Query MongoDB in Meteor "each context" nested

Example:
<template name="list_customers">
<p><h3>List Customers</h3></p>
{{#each customers}}
{{> list_customers_content}}
{{/each}}
</template>
<template name="list_customers_content">
..display all customer data from "Customers.find({})...
{{> list_customers_content_ip}}
</template>
<template name="list_customers_content_ip">
.. display data from Customers_ip.find({}) based on #each customer object id.
</template>
Template.list_customers.helpers({
customers() {
return Customers.find({});
},
});
How can this be done in fewest possible queries to two different collections, and is there any way to use the customers context object id? Please write full example.
What should the helper for Customers_ip.find() look like?
You need to pass the current document (which is this inside the #each context) to the list_customers_content template in order to further process it.
The name of the parameter will be the name to access the value in the child template.
Example:
{
name: "John Doe",
_id: "1232131",
}
<template name="list_customers">
<p><h3>List Customers</h3></p>
{{#each customers}}
{{> list_customers_content customer=this}}
{{/each}}
</template>
<template name="list_customers_content">
<span>Name: {{customer.name}}</span><!-- John Doe -->
{{> list_customers_content_ip customerId=customer._id}}
</template>
<template name="list_customers_content_ip">
{{#each customerIp customerId}}
<span>IP: {{this.ip}}</span>
{{/each}}
</template>
A helper for customerIp could look like this:
Template.list_customers_content_ip.helpers({
customerIp(customerId) {
// assumes, that these documents have
// a field named "customerId"
return Customers_ip.find({ customerId });
},
});

Group and display data

Here is my data
data = [
{ category : "Cat1"},
{ category : "Cat2"},
{ category : "Cat3"},
{ category : "Cat4"},
{ category : "Cat5"},
{ category : "Cat6"}]
Let suppose i have it in a collection named myData
What i want is to group and display my data in group of 2.
Then i display it in a navbar (in a dropdown in fact) like this
<ul>
{{#each group}}
<li class="col-md-2">
<ul>
{{#each categories}}
<li>{{category}}</li>
{{/each}}
</ul>
{{/each}}
<ul>
What i am asking is how to group the data in my helpers or in mongodb so that i could get this result.
I'm not 100% clear what you mean by "group", but assuming you are using Boostrap navbar dropdowns, you could group them with separators:
{{#each categories}}
<li>{{category}}</li>
{{#if doSeparator #index}}
<li role="separator" class="divider"></li>
{{/if}
{{/each}}
and the doSeparator helper goes in your .js file:
doSeparator( index ) {
return (index % 2);
}
If on the other hand you want submenus for each group you will need to reorganize your array in two levels.
Another approach could be:
<ul>
{{#each groups}}
<li>
<ul>
{{#each this}}
<li>{{category}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
Then in your Template helper:
import { Template } from 'meteor/templating';
import chunk from 'lodash/chunk';
import { myData } from '/imports/api/mydata/collection';
import './main.html';
Template.someTemplate.helpers({
groups() {
return chunk(myData.find().fetch(), 2);
},
});
This uses lodash's chunk function to split the returned array into groupings of 2 items (so you'll want to meteor npm install --save lodash if you haven't already).
The above will give you output like:
<ul>
<li>
<ul>
<li>1</li>
<li>2</li>
</ul>
</li>
<li>
<ul>
<li>3</li>
<li>4</li>
</ul>
</li>
<li>
<ul>
<li>5</li>
<li>6</li>
</ul>
</li>
</ul>
You can break it up into groups of 2 inside a helper using underscore's map and compact
Template.hello.helpers({
groups() {
// var data = myData.find().fetch();
var data = [
{ category : "Cat1"},
{ category : "Cat2"},
{ category : "Cat3"},
{ category : "Cat4"},
{ category : "Cat5"},
{ category : "Cat6"}];
return _.chain(data).map(function(item, index){
return (index % 2) ? false : data.slice(index, index + 2);
}).compact().value();
},
});
Then, in your template you can use a nested #each in to loop through groups
<template name="hello">
<ul>
{{#each group in groups}}
<li class="col-md-2">
<ul>
{{#each category in group}}
<li>{{category.category}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</template>

Unable to get mizzao/meteor-autocomplete to work with collection

I am using mizzao/meteor-autocomplete and am having problems in trying to get it to work.
When viewing the page in my browser, I am getting no results at all when typing any text. I've created the appropriate collection:
Institutions = new Mongo.Collection("institutions");
and know that there is data in the actual db, however still no success.
I've included my files below.
publications.js (located in the server folder)
Meteor.publish('institutions', function(args) {
return Institutions.find({}, args);
});
registrationStart.js
I've two helpers; one that actually powers the search and the other that should be returning the institutions. I have also tried this with the token: '#' argument with no success.
if (Meteor.isClient) {
Template.registrationStart.helpers({
settings: function() {
return {
position: "top",
limit: 7,
rules: [{
collection: Institutions,
field: "name",
options: '',
matchAll: true,
template: Template.institutionSelectDisplay
}]
};
},
institutions: function() {
return Instititions.find();
}
});
Template.registrationStart.events({
"autocompleteselect input": function(event, template, doc) {
// Session.set(event.target.name, event.target.value);
console.log("selected: ", doc);
console.log("event.target.name: ", event.target.name);
console.log("event.target.value: ", event.target.value);
}
});
}
registrationStart.html template
<template name="registrationStart">
<div class="panel-body" id="loginForm">
<h2 class="pageTitle">veClient Registration</h2>
<form>
<div> </div>
<fieldset>
{{> inputAutocomplete settings=settings id="institution" class="input-xlarge" placeholder="type institution here"}}
</fieldset>
<div> </div>
<button type="submit" class="btn btn-primary btn-sm">Continue Registration</button>
</form>
</div>
</template>
And the template to be rendered
<template name="institutionSelectDisplay">
<p class="inst-state">{{city}}, {{state}}</p>
<p class="inst-name">{{name}}</p>
<p class="inst-description">{{email}}</p>
</template>
Problem resulted because there was no subscription to the "institutions" publication. So need to add a subscribe statement to the registrationStart.js file:
Meteor.subscribe('institutions');

How do I hide the parent element of one that triggered an action with jQuery?

I have this code in html (notice the numers 1 and 2in the outside and inside elements):
<div class="list_item" id="item_1">
<div class="list_item_int">My first line</div>
<div class="eval_buttons">
<div class="approve" id="1"></div>
<div class="dismiss" id="1"></div>
</div>
<div class="list_item" id="item_2">
<div class="list_item_int">My second line</div>
<div class="eval_buttons">
<div class="approve" id="2"></div>
<div class="dismiss" id="2"></div>
</div>
Then I have this script:
$().ready(function(){
$(".approve").click(function(){
$.post(
"php/judge_work.php",
{action : "1", work_info : this.id},
function(data){
$("#item_" + this.id).hide("slow");
}
);
});
$(".dismiss").click(function(){
$.post(
"php/judge_work.php",
{action : "0", work_info : this.id},
function(data){
alert(data);
}
);
});
});
Is there a way to make $("#item_" + this.id).hide("slow"); work? thanks on your kind response.
You can use .closest(), like this:
$(this).closest(".list_item") //gets the ancestor <div class="list_item">
In your case since this won't be the clicked element in the $.post() callback, it'll look like this:
$(".approve").click(function(){
var li = $(this).closest(".list_item");
$.post(
"php/judge_work.php",
{action : "1", work_info : this.id},
function(data){
li.hide("slow");
}
);
});