I'm doing some intro Meteor stuff, and I'm having trouble getting the correct values from my Collection. I'm trying to track ownership of the central site, as claimed by a button. The program is currently just an extension of the Try Meteor task tutorial. Anyways, here's the HTML and JS:
--------------HTML------------
<head>
<title>Todo List</title>
</head>
<body>
<div class="container">
<header>
<h1>Todo List</h1>
<form class="new-task">
<input type="text" name="text" placeholder="Type to add new tasks" />
</form>
{{> ownerclaim}}
<h4>Current owner: {{ownerget}}</h4>
</header>
<u1>
{{#each tasks}}
{{> task}}
{{/each}}
</u1>
{{> loginButtons}}
</div>
</body>
<template name="task">
<li class="{{#if checked}}checked{{/if}}">
<button class="delete">×</button>
<input type="checkbox" checked="{{checked}}" class="toggle-checked" />
<span class="text">{{text}}</span>
</li>
</template>
<template name="ownerclaim">
<button class="claim">Claim website</button>
</template>
<template name="ownership">
<span class="text">{{text}}</span>
</template>
-----------JS---------------
OwnerC = new Mongo.Collection("owner");
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
Meteor.subscribe("own");
console.log(OwnerC.findOne({}));
Session.set("currentOwner", OwnerC.findOne({}));
Template.body.helpers({
tasks: function () {
return Tasks.find({}, {sort: {createdAt: -1}});
},
ownerget: function () {
console.log("JOHNNN");
console.log(Session.get("currentOwner"));
return Session.get("currentOwner");
}
});
Template.body.events({
"submit .new-task": function (event) {
var text = event.target.text.value;
Tasks.insert({
text: text,
createdAt: new Date(),
owner: Meteor.userId(),
username: Meteor.user().username
});
event.target.text.value = "";
return false;
}
});
Template.task.events({
"click .toggle-checked": function() {
Tasks.update(this._id, {$set: {checked: ! this.checked}});
},
"click .delete": function() {
Tasks.remove(this._id);
}
});
Template.ownerclaim.events({
"click .claim": function() {
OwnerC.update({}, {$set: {text: Meteor.user._id}});
}
})
Accounts.ui.config({
passwordSignupFields: "USERNAME_ONLY"
});
}
if(Meteor.isServer) {
console.log("YOYOYOYOYOYO");
Meteor.startup( function(){
console.log("YOYO");
OwnerC.insert({
text: "none",
createdAt: new Date(),
owner: "0",
username: "0"
});
console.log(OwnerC.findOne({}));
Meteor.publish("own", function() {
return OwnerC.find({});
});
});
}
For some reason, my server logs are showing OwnerC to contain the object, but the client logs are showing it as an empty Collection, and findOne in the client is returning undefined. Anyone know where I'm going wrong?
Related
I have the 2 following templates which I am trying to bind functions to. As you can see it's a simple app to add objects with names and scores into its mongoDB.
Here is the HTML File:
<head>
<title>Leaderboard</title>
</head>
<body>
<h1>Leaderboard</h1>
{{> leaderboard}}
<br /><br />
{{>addPlayerForm}}
</body>
<template name="leaderboard">
<ul>
{{#each player}}
<li class="player {{selectedClass}}"> {{name}} : {{score}} </li>
{{/each}}
</ul>
<ul>
{{#if showSelectedPlayer}}
<li> Selected Player: {{showSelectedPlayer.name}} </li>
{{/if}}
</ul>
<input type="button" class="increment" value="Give 5 Points"/>
<input type="button" class ="decrement" value="Minus 5 Points"/>
</template>
<template name="addPlayerForm">
<form class="add-form">
<input type="text" name="PlayerName" placeholder="Add player name here" />
<input type="submit" name="Add Player" />
</form>
</template>
Complete JS File:
PlayersList = new Mongo.Collection('Players');
console.log(PlayersList);
if(Meteor.isClient){
Template.leaderboard.helpers({
'player': function(){
return PlayersList.find( )
},
'selectedClass':function(){
var playerId=this._id;
var selectedPlayer=Session.get('selectedPlayer');
if (playerId==selectedPlayer){
return "selected"
}
},
'showSelectedPlayer':function(){
var selectedPlayer = Session.get('selectedPlayer');
return PlayersList.findOne(selectedPlayer)
}
});
Template.leaderboard.events({
'click .player':function(){
var playerID = this._id; //this refer to the current context:playerclicked
Session.set('selectedPlayer', playerID);
var selectedPlayer = Session.get('selectedPlayer');
console.log(selectedPlayer);
},
'click .increment':function(){
var selectedPlayer = Session.get('selectedPlayer');
PlayersList.update(selectedPlayer,{$inc:{score:5}});
},
'click .decrement':function(){
var selectedPlayer = Session.get('selectedPlayer');
PlayersList.update(selectedPlayer,{$inc:{score:-5}});
}
});
Template.addPlayerForm.events({
'submit form': fucntion(event){
event.preventDefault();
var PlayerNameVar = event.target.PlayerName.value;
console.log(PlayerNameVar);
PlayersList.insert({
name:PlayerNameVar,
score:0
});
}
});
}
if(Meteor.isServer){
console.log("Hello Server!");
}
This is the error:
While processing files with ecmascript (for target web.browser):
main.js:38:34: Unexpected token, expected "," (38:34)
While processing files with ecmascript (for target os.windows.x86_32):
main.js:38:34: Unexpected token, expected "," (38:34)
Line 38 is in Template.addPlayerForm.events:
'submit form': fucntion(event){
As Ankit has found out, you need to correct the typo. It is function, also I suggest you use editors like Sublime, Atom or VS CODE to get rid of such typos.
I want to create a simple Login, Register and Logout menu with Meteor and Iron Router. Before I used the Iron Router package I could submit a new user and easily login or logout. Therefore I had this code in my html document:
<body>
{{#if currentUser}}
{{> dashboard}}
{{else}}
{{> register}}<br>
{{> login}}
{{/if}}
</body>
Now I want to route the login and register form. If you press the Login button we should get: lochalhost:3000 login (which works fine).
But I don't know:
why I can't submit a new user anymore
how I can change from the successful login route to the dashboard route
and probably how I can logout (couldn't test it yet)
I'm new to JS and Meteor. Still I didn't find a solution in the Internet or a way to fix it on my own.
My complete document looks like:
main.html:
<head>
<title>Routing</title>
</head>
<body>
{{#if currentUser}}
{{> dashboard}}
<!--{{else}}
{{> register}}<br>
{{> login}} -->
{{/if}}
</body>
<template name="main">
<h1>Text</h1>
{{> navigation}}
{{> yield}}
<hr />
<p>
Copyright ©
</p>
</template>
<template name="home">
<p>
Welcome to the <b>Text</b> website.
</p>
</template>
<template name="navigation">
<ul>
<li>Home</li>
<li>Register</li>
<li>Login</li>
</ul>
</template>
<template name="register">
<form>
<input type="text" id="username">
<input type="text" id="email">
<input type="password" id="password">
<input type="submit" value="Register">
</form>
</template>
<template name="login">
<form>
<input type="text" id="login-email">
<input type="password" id="login-password">
<input type="submit" value="Login">
</form>
</template>
<template name="dashboard">
<p>
Yor're logged in.
Logout
</p>
</template>
main.js
Router.route('register'); // Default name is register
Router.route('login'); // Default name is login
Router.route('dashboard');
Router.route('/', {
name: 'home',
template: 'home'
});
Router.configure({
layoutTemplate: 'main'
});
if (Meteor.isClient) {
Template.register.events({
'submit form': function(event, template) {
event.preventDefault();
var usernameVar = template.find('#username').value;
var emailVar = template.find('#email').value;
var passwordVar = template.find('#password').value;
Accounts.createUser({
username: usernameVar,
email: emailVar,
password: passwordVar
})
}
});
Template.login.events({
'submit form': function(event, template) {
event.preventDefault();
var emailVar = template.find('#login-email').value;
var passwordVar = template.find('#login-password').value;
Meteor.loginWithPassword(emailVar, passwordVar);
}
});
Template.dashboard.events({
'click .logout': function(event) {
event.preventDefault();
Meteor.logout();
prompt("You successfully logged out");
}
});
}
And I added:
the iron:router package
meteor add accounts-ui accounts-password
I would say, do read the official documentation for Iron Router and Meteor to have better understanding. I took your code and did some testing, it works fine. I only added iron:router accounts-ui (Look up documentation for this, you can create easy login and signup with this package) and accounts-password.
main.html
<head>
<title>Routing</title>
</head>
<body>
{{#if currentUser}}
{{> dashboard}}
<!--{{else}}
{{> register}}<br>
{{> login}} -->
{{/if}}
</body>
<template name="main">
<h1>Text</h1>
{{> navigation}}
{{> yield}}
<hr />
<p>
Copyright ©
</p>
</template>
<template name="home">
<p>
Welcome to the <b>Text</b> website.
</p>
</template>
<template name="navigation">
<ul>
<li>Home</li>
{{#unless currentUser}}
<li>Register</li>
<li>Login</li>
{{/unless}}
</ul>
</template>
<template name="register">
{{#unless currentUser}}
<form>
<input type="text" id="username">
<input type="text" id="email">
<input type="password" id="password">
<input type="submit" value="Register">
</form>
{{/unless}}
</template>
<template name="login">
{{#unless currentUser}}
<form>
<input type="text" id="login-email">
<input type="password" id="login-password">
<input type="submit" value="Login">
</form>
{{/unless}}
</template>
<template name="dashboard">
<p>
Yor're logged in.
Logout
</p>
</template>
main.js
goHome =function(){
if(Meteor.userId()){
Router.go('/');
}
}
Router.configure({
layoutTemplate: 'main'
});
Router.route('/register', {
template:'register',
onBeforeAction:function(){
goHome();
this.next();
}
}); // Default name is register
Router.route('/login', {
template:'login',
onBeforeAction:function(){
goHome();
this.next();
}
});
Router.route('/dashboard',{
template:'dashboard'
})
Router.route('/', {
name: 'home',
template: 'home'
});
if (Meteor.isClient) {
Template.register.events({
'submit form': function(event, template) {
event.preventDefault();
var usernameVar = template.find('#username').value;
var emailVar = template.find('#email').value;
var passwordVar = template.find('#password').value;
Accounts.createUser({
username: usernameVar,
email: emailVar,
password: passwordVar
}, function(error){
if(!error){
Router.go('/');
}
})
}
});
Template.login.events({
'submit form': function(event, template) {
event.preventDefault();
var emailVar = template.find('#login-email').value;
var passwordVar = template.find('#login-password').value;
Meteor.loginWithPassword(emailVar, passwordVar, function(error){
if(!error){
Router.go('/');
}
});
}
});
Template.dashboard.events({
'click .logout': function(event) {
event.preventDefault();
Meteor.logout();
prompt("You successfully logged out");
}
});
}
Here's my simple template:
<template name="feed">
{{> crewChat}}
{{> statusSubmit}}
{{#each statuses}}
{{> statusItem}}
{{/each}}
</template>
In my groupChat.html and groupChat.js files:
<template name="crewChat">
<div class="post-item">
<div class="ui feed">
{{#each messages}}
{{> crewChatMessage}}
{{/each}}
</div>
</div>
<form class="new-message">
<textarea id="message" name="content" rows="2"></textarea>
<div class="post-actions text-right">
<input type="submit" value="Submit" class="compact tiny ui primary button">
</div>
</form>
</template>
Template.crewChat.events({
'submit form': function(e) {
e.preventDefault();
var crewMessage = {
content: e.target.content.value
}
Meteor.call('createCrewMessage', crewMessage, function(error, result) {
if (error)
return alert(error.reason);
console.log("Create new crew message.");
$(e.target.content).val("");
});
}
});
Template.crewChat.helpers({
messages: function() {
return CrewMessages.find({}, {sort: {submitted: -1}});
}
});
When I submit a new message, I can see it added using Mongol (and visually for a split second), but it's removed immediately after.
Meteor.methods({
createCrewMessage: function(crewMessageAttributes) {
var user = Meteor.user();
var crewMessage = _.extend(crewMessageAttributes, {
userId: user._id,
author: user.profile.firstName,
submitted: new Date()
});
var crewMessageId = CrewMessages.insert(crewMessage);
return { _id: crewMessageId };
}
});
Any ideas why this would be happening?
I had forgotten to subscribe to my published collection.
Meteor.subscribe('crewMessages');
IM trying out Meteor ToDo-list tutorial but I have problem where I have a form and I should be able to insert the values into the database but it doesn't work. When I hit enter nothing happens.
Here my my html:
<head>
<title>Todo list</title>
</head>
<body>
<div class="container">
<header>
<h1>Tee asjad ära!</h1>
<form class="new-task">
<input type="text" placeholder="Type to add new tasks" />
</form>
</header>
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
</div>
</body>
<template name="task">
<li>{{text}}</li>
</template>
here is the .js file:
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
//see kood jookseb ainult kliendipoolel
Template.body.helpers({
tasks: function () {
return Tasks.find({});
}
});
Template.body.events({
"submit .new-task": function (event) {
var text = event.target.text.value;
Tasks.insert({
text: text,
createdAt: new Date()
});
event.target.text.value = "";
return false;
}
});
}
When I enter values from command line to the database it works fine.
Your input is missing name="text", which is the attribute that lets you access the value through event.target.text.value.
Were you getting an error in the JavaScript console in your browser?
I have the below which displays a list of products. When I click on a product I would like to see just the product information.
The only way I've managed to get the product info to appear is to use the {{outlet}} or {{render}} on the parent products template which is not what I want.
var App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
});
App.ProductsController = Ember.ArrayController.extend({
sortProperties: ['id']
});
App.Router.map(function () {
this.resource('products', function () {
this.resource('product', { path: ':product_id' });
});
});
App.ProductsRoute = Ember.Route.extend({
model: function () {
return App.Products.find();
}
});
// Models
App.Store = DS.Store.extend({
revision: 11,
adapter: 'DS.FixtureAdapter'
});
App.Products = DS.Model.extend({
title: DS.attr('string'),
artist: DS.attr('string'),
image: DS.attr('string'),
price: DS.attr('number'),
url: DS.attr('string')
});
App.Products.FIXTURES = [
{
id: 1,
title: 'The Door',
artist: 'Religious Knives',
image: 'http://ecx.images-amazon.com/images/I/51og8BkN8jL._SS250_.jpg',
large_image: 'http://ecx.images-amazon.com/images/I/51og8BkN8jL._SS500_.jpg',
price: 9.98,
url: 'http://www.amazon.com/Door-Religious-Knives/dp/B001FGW0UQ/?tag=quirkey-20'
},
//etc etc
];
-------------MARKUP------------
<script type="text/x-handlebars" data-template-name="products">
<span>{{ controller.model.length }} item(s) in stock</span>
<div>
{{#each product in controller.model}}
<div class="item">
<div class="item-image">
{{#linkTo "product" product}}
<img {{bindAttr src="product.image" alt="product.title"}}>
{{/linkTo}}
</div>
<div class="item-artist">{{product.artist}}</div>
<div class="item-title">{{product.title}}</div>
<div class="item-price">${{product.price}}</div>
</div>
</div>
{{/each}}
{{render product}}
</script>
<script type="text/x-handlebars" data-template-name="product">
<div class="item-detail">
<div class="item-image">
<img {{bindAttr src="large_image" alt="title"}} />
</div>
<div class="item-info">
<div class="item-artist">{{artist}}</div>
<div class="item-title">{{title}}</div>
<div class="item-price">${{price}}</div>
<div class="item-form">
<p>
<label>Quantity:</label>
<input type="text" size="2" data-bind="value: quantity" />
</p>
<p>
<button data-bind="click: $parent.addItem">Add to Cart</button>
</p>
</div>
<div class="item-link"><a {{bindAttr href="url"}}">Buy this item on Amazon</a></div>
<div class="back-link">« Back to Items</div>
</div>
</div>
</script>
UPDATE: This kind of works:
The issue is when going from a product back to products the products are no longer listed
App.ProductsRoute = Ember.Route.extend({
model: function () {
return App.Products.find();
}
});
App.ProductRoute = Ember.Route.extend({
model: function (params) {
return App.Products.find(params.product_id);
},
renderTemplate: function () {
this.render('product', { // the template to render
into: 'application', // the template to render into
outlet: 'main', // the name of the outlet in that template
});
}
});
You could change change your router mappings to something like this:
App.Router.map(function () {
this.route('products');
this.route('product', { path: 'product/:product_id' });
});
Also consider using an index route which transfers you to a specific location when the page loads:
App.IndexRoute = Em.Route.extend({
redirect: function() {
this.transitionTo('products');
}
});
Fiddle: http://jsfiddle.net/schawaska/d2FtF/
Run: http://jsfiddle.net/schawaska/d2FtF/show