Data is not transferring from Client to Server in Meteor - mongodb

Main purpose of this code is, when we have data in database it should fetch and display on the browser. But i couldn't find it.
Problem is transferring data to the Server.
After running the meteor and enter some value from console of the browser,i am not able to see them back on the browser.But i am able to find them with in console by using the command "Tdos.find().fetch()",it is showing arrays that i have entered but if i am trying to find in mongodb console, we couldn't find it. Can Some one figure out my problem and where am i going wrong?
<head>
<title>simpletodos</title>
</head>
<body>
{{> todoList}}
</body>
<template name="todoList">
<h3>Todos</h3>
<ul>
{{#each tdos}}
{{> todo}}
{{/each}}
</ul>
<button class="add-todo">Add todo</button>
</template>
<template name="todo">
<li>
{{label}}
</li>
</template>
Client/Main.js
if(Meteor.isClient) {
Template.todoList.helpers({
todos: function() {
return Tdos.find();
}
});
if(Meteor.isServer) {
}
}
Server/main.js
import { Meteor } from 'meteor/meteor';
Tdos = new Mongo.Collection("tdos");
Meteor.startup(() => {
// code to run on server at startup
});

In your server, you define the collection like this:
Tdos = new Mongo.Collection("tdos");
Which means the collection in Mongo is todos, and you can list the contents with
db.todos.find()
You can insert a record in mongo using this:
db.todos.insert({label: "My first to do"})
In Meteor when you want to fetch or insert/update, you use Tdos, eg
Tdos.insert(...};
Your helper lets the data be available as an array within your code. I think you need to change that to be
todos: function() {
return Tdos.find().fetch();
}

Related

How do I list Meteor users and only show their first email address?

I'm listing all the Meteor users in a template:
<template name="userList">
<ul>
{{#each users}}
<li>
{{_id}}<br>
Emails:
{{#each emails}}
{{address}},
{{/each}}
</li>
{{/each}}
</ul>
</template>
Here's my helper:
Template.userList.helpers({
users : function() {
return Meteor.users.find({});
}
});
This works, but since I'm not using usernames, I only want to list the first email address and not have to handle it with an {{#each}} in the template. Ideally, I'd have a value for users.primaryEmail, so I changed the helper to this:
Template.userList.helpers({
users : function() {
var rawUsers = Meteor.users.find({});
var users = [];
_.each(rawUsers, function(user) {
user.primaryEmail = user.emails[0].address;
users.push(user);
})
return users;
}
});
...and updated my template code to output {{primaryEmail}}, but it doesn't seem to return any users at all now. What am I missing?
Figured out that I needed to use .fetch() in order to get the results as an array & make users.emails[0] work:
var rawUsers = Meteor.users.find({}).fetch();

MeteorJS: Autoform + CollectionFS, associating images from an FS.Collection with Corresponding Mongo.Collection Document?

I'm building a very small Meteor application simply to get a better understanding of Autoform and CollectionFS, and their use together. I currently have everything set up with the following packages:
iron:router, aldeed:autoform, aldeed:collection2, cfs:standard-packages,
cfs:filesystem, cfs:autoform
I have a sample Mongo Collection assigned to "Books" set up with a SimpleSchema attached, with fields from the demo like title and author. The corresponding code for the file upload is:
fileId: {
type: String,
autoform: {
afFieldInput: {
type: "cfs-file",
collection: "images"
}
}
}
The FS.Collection code is:
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})]
});
This is in conjunction to a quickform: {{> quickForm collection="Books" id="insertBookForm" type="insert"}}
The insert is fine, and I can iterate over the documents and display the various fields using spacebars and a helper function called "books", like so:
{{#each books}}
<li>{{title}} by {{author}}</li>
{{/each}}
I can also iterate over images uploaded to the FS.Collection with a helper returning the entire collection called "files," and looping over them like so:
{{#each files}}
<img src="{{this.url}}" />
{{/each}}
The issue I'm having is linking the two together. I want to be able to do something along the lines of:
{{#each books}}
<li>{{title}}, by {{author}} <img src="The-Corresponding-Image}}" /></li>
{{/each}}
Obviously not that exact layout, but I basically just want to be able to print images with their corresponding titles and authors to be able to use autoform with collectionfs for my needs.
I'm stuck trying to retrieve the fileId from a specific document in the Books collection, and then plugging that into an Images.findOne({fileId: fileId}) and linking the two together.
Can anyone point me in the right direction?
I was able to figure it out thanks to Ethaan's guidance. What I had to do was the following:
Autoform Hook:
AutoForm.hooks({
insertBookForm: {
after: {
insert: function(error, result, template) {
insertedFile = Books.findOne(result).fileId;
Images.update({_id: insertedFile}, {$set: {'book': result}});
}
}
}
});
I set a field of 'book' to the _id of the document being inserted (stored in the result parameter) right after it was inserted.
This is my corresponding HTML:
{{#each books}}
<li>{{title}} by {{author}}</li>
{{#with files}}
<img src="{{this.url}}" />
{{/with}}
{{/each}}
And my helpers:
Template.layout.helpers({
books: function () {
return Books.find({});
},
files: function() {
return Images.findOne({book: this._id});
}
});

Selecting attributes from an object when using find() in MongoDB/Meteor

So I'm new to Meteor, and have been playing around with it, but have hit a few issues with moving over to Mongo.
Below is a simple example, where I have inserted some documents into my collection, but cannot seem to extract the attributes properly.
Here is my code (and my result vs expected result is below it)
vizart.js
ContentPieces = new Mongo.Collection("content");
if (Meteor.isClient) {
Template.loggedInDash.helpers({
content: function () {
return ContentPieces.find({});
}
});
}
vizart.html
<template name="loggedInDash">
{{#if currentUser}}
<p>Here is the content you've created</p>
<ul>
{{#each content}}
<li>{{content}}</li>
{{/each}}
</ul>
{{/if}}
</template>
Result (just pasted from the app in my browser)
Here is the content you've created
[object Object]
[object Object]
[object Object]
Expected
As you can see, I am not 100% sure how to pull out an attribute. For example, each document has a name attribute, and I'd like to spit that out in the list instead. Any help or guidance on how to select the name attribute from the content collection?
Thanks in advance!
The meteor template language (spacebars) is inspired by handlebars. I'd recommend having a look at both sets of docs, but the handlebars documentation will get you up to speed with the basic syntax.
In your example, if each document in ContentPieces has a name then you can add it to your list like this:
<ul>
{{#each content}}
<li>{{name}}</li>
{{/each}}
</ul>
I'd also recommend having a look at this post to better understand template data contexts.
In your process you are displaying the whole document, if you just want to display the name attribute you can do it by
if (Meteor.isClient) {
Template.loggedInDash.helpers({
content: function () {
var name=ContentPieces.find({}).name;
if(name)
return name;
}
});
You can just pass the field name that you want to display

Meteor how to retrieve an array of questions from the mongo db and displaying just one of them within the app

As I am new to programming and Meteor I am currently building a (simple) Quizz app using Meteor.js. I followed the discover Meteor Guide book and rebuilding their example microscope project into a quiz. I am currently struggling with retrieving the array of questions from the mongo db and displaying just one of them within the app.
The data within my collection currently looks like this:
Quizzes.insert(
{"quiztitle": "Quiz One",
"quizquestions": ["Q1.1", "Q1.2"]
}),
I am currently displaying all of them thorugh
<template name="quizPage">
<h3>
{{#each quizquestions}}
{{> quizQuestion}}
{{/each}}
</h3>
and
<template name="quizQuestion">
<div class="quiz">
<div class="quiz-content">
{{this}}
</div>
</div>
I have tried several solutions already to getting only the first question to display:
1.Substituting the array number through a helper function with Spacebars. Although the helper worked (it returned a specific number for instance 0), and the array by itself ( 0 between brackets). Meteor does not seem to allow spacebar inserts into array brackets.
<template name="quizQuestion">
<div class="quiz">
<div class="quiz-content">
{{quizquestions.[{{questionnumber}}]}}
</div>
</div>
2.aReturning a specific field through a mongodb query. for example
Return Quizzes.find( { quiztitle: 'Quiz One' }, { quizquestion: 1, _id:0, quiztitle: 0 });
Unfortunately this is only allowed on the server side. I have also tried to save the array resulting from the return into a global variable within the lib folder
questionArray = Quizzes.find( { quiztitle: 'Quiz One' }, { quizquestion: 1, _id:0, quiztitle: 0 } );
This is also the case when I try slicing the collection, which is suggested in a different post
3.As this also does not seem to work I have tried publishing a subset of the collection for use in a specific quiz. The problem I have here is that the collection seems to be published in its entirety. I publish the collection on the frontpage.js through
Meteor.subscribe('quizzes');
I have also tried subscribing within an autorun as is suggested in the documentation at http://docs.meteor.com/#meteor_subscribe
Deps.autorun(function () {
Meteor.subscribe("quizzes")});
Question: Could you help me find a way to return only the questions array and either save it to a global variable or return it through a helper. I hope you can help me out, thanks a lot,
Meteor Beginner.
First, you need to make sure the data is available on the client. In chrome, open up your javascript console (cmd+option+j) and paste Quizzes.find().fetch() and you should see your objects. Assuming that is good, continue...
To get your questions to display, you can return the specific question to a {{#with}} block like this:
{{#with question}}
<li>{{this}}</li>
{{/with}}
Your question helper could look something like this...
Template.TEMPLATE_NAME.helpers({
question: function(){
var currentQuestion = Session.get('currentQuestion') || 0;
return Quizzes.findOne({}).quizquestions[currentQuestion]
}
});
Then you can increment the Session variable each time you answer or go to the next question in a Meteor event, something like this:
Template.TEMP_NAME.events({
'click .next-question': function(){
var num = Session.get('currentQuestion') + 1;
Session.set('currentQuestion', num);
}
});
This will cause the helper to rerun and your new question will be passed back to the {{#with}} block.
In the quizPage template, add a helper which finds a single question:
Template.quizPage.firstQuestion = function() {
return this.quizquestions[0];
}
Then use it:
<template name="quizPage">
<h3>
<!-- #with is like #each, but for a single item -->
{{#with firstQuestion}}
{{> quizQuestion}}
{{/with}}
</h3>
</template>

Meteor Subscriptions - Customised Helper Function Not working

When I subscribe to a mongodb collection in the client and publish in the server whilst switch auto-publish off. Do I need to specify each individual find query I am declaring in my helper functions within the publish method? Or is it sufficient to just return Meteor.collection.find() in the Publish statement and that should give access to the entire collection?
Lost? Please see below
In my application I have 2 mongo collections setup. One Called 'Tables' and another called 'Rolls'.
In my client.js file I have two handlebars helper functions:
Template.tables.tableList = function(){
return Tables.find();
}
Template.tableBox.table = function(tableID){
return Rolls.find({"Roll.tableName": tableID}, {sort: {date: -1}, limit:10});
}
to correspond to my templates:
<template name="tables">
<div class="table-area">
{{#each tableList}}
{{> tableBox}}
{{/each}}
</div>
</template>
<template name="tableBox">
<table id="{{name}}" class="table table-condensed">
<tr class="n{{minBet}}">
<th>{{name}}</th>
<th> Min:</th>
<th>{{minBet}}</th>
<th>{{cPlayers}}</th>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
<td>D3</td>
<td>Tot</td>
</tr>
{{#each table name}}
{{> tableRow}}
{{/each}}
</table>
</template>
<template name="tableRow">
<tr class={{rowColor Roll.dice1 Roll.dice2 Roll.dice3 Roll.total}} "bold">
<td>{{Roll.dice1}}</td>
<td>{{Roll.dice2}}</td>
<td>{{Roll.dice3}}</td>
<td>{{Roll.total}}</td>
</tr>
</template>
The first helper function returns all the Tables in the collection.
The 2nd returns the last 10 Rolls in descending order.
Using autopublish - everything works fine. My page shows all the tables and within each table the last 10 dicerolls.
When I switch autopublish off and try and setup corresponding subscribe/publish statements. It doesn't work. Only the Tables are shown - but the data from the Rolls collection is not populating my template.
Corresponding Subscribe and Publish Code:
In client.js:
Meteor.subscribe('tables');
Meteor.subscribe('rolls');
In server/publications.js:
Meteor.publish('tables', function() {
return Tables.find();
});
Meteor.publish('rolls', function() {
return Rolls.find();
});
My assumption is that it is to do with my slightly complicated query in my handlebars helper function for the rolls table? Is it not a simple subscribe to the whole collection (i.e. publish the return of Rolls.find()) and then be able to access all mongo query subsets that I define within my client? Is there something I'm missing here? Thanks for any help.
This seems like it is due to Rolls collection not being fully loaded on the client yet at the time you query for it. You can try something like:
Template.tables.tableList = function(){
return Tables.find();
}
Template.tableBox.table = function(tableID){
Deps.autorun(function () {
return Rolls.find({"Roll.tableName": tableID}, {sort: {date: -1}, limit:10});
});
}
The Deps.autorun(func) block runs the encapsulated function whenever the reactive dependencies change.