I'm starting to learn Meteor.js and, when I've removed autopublish and insecure, my application doesn't work any longer.
I can insert data to database but I can't retrive anything by database.
No errors in console.
This is my code:
client/main.html
<head>
<title>Blog Test</title>
</head>
<body>
<h1>Blog Test</h1>
{{>blog}}
{{>ListBlogs}}
</body>
<template name="blog">
<form class="blog-post" id="blog-post" role="form">
<label id="label-title" class="label-title">Titolo:</label>
<input id="input-title" class="input-title" placeholder="Titolo">
<br>
<label id="label-text" class="label-text">Testo:</label>
<textarea id="input-text" class="input-text" placeholder="Testo"></textarea>
<br>
<button type="submit" class="blog-btm">Submit</button>
</form>
</template>
<template name="ListBlogs">
{{#each posts}}
<h2>{{title}}</h2>
<p>{{text}}</p>
{{/each}}
</template>
client/main.js
Template.blog.events({
'submit #blog-post':function (e){
e.preventDefault();
var title = $('.input-title').val();
var text = $('.input-text').val();
Meteor.call('submitPost',title,text);
}
});
Meteor.subscribe('posts');
server/server.js
Meteor.methods({
'submitPost':function(title, text){
console.log("Titolo: " + title);
console.log("Testo:" + text);
Blogs.insert({title:title, text:text});
}
});
Meteor.publish('posts', function() {
return Blogs.find();
});
lib/blog.js
Blogs = new Meteor.Collection('blogs');
We fixed this in IRC I believe :-)
The problem is that your template ListBlogshas no idea what posts means. You will have to define a helper, so that the {{#each posts}} block gets a meaning.
Fortunately this only requires a very quick fix:
Template.ListBlogs.posts = function(){
return Blogs.find().fetch();
}
Put this in your client/main.js and all posts appear in realtime.
your code it's ok, though you must to try subscribe on collection of this way
Tracker.autorun(function () {
Meteor.subscribe("posts");
});
http://docs.meteor.com/#tracker_autorun
and after that you must to create the helpers, for example...
Template.blog.helpers({
})
Template.ListBlogs.helpers({
posts: function(){
return Posts.find({});
}
})
Related
I am trying to combine 2 beginner classes together (https://www.meteor.com/tutorials/blaze/templates & http://meteortips.com/second-meteor-tutorial/iron-router-part-1/). I have been able to complete both classes individually with no problem.
I am using Iron:Router to route to various templates. I run in to issues when I try to access a template within a template. The proper results do not get displayed on the " aostasks"page.
.js:
Router.route('aostask', {
template: 'aostask'
});
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
// This code only runs on the client
Template.registerHelpers('task', function () {
return tasks.find({});
})
};
.html:
<template name= "aostask">
<head>
<title>Todo List</title>
</head>
<body>
<div class="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
</div>
</body>
</template>
<template name="task">
<li>{{text}}</li>
</template>
Result:
A page with the correct headers.However, it does not list the tasks i have in my mongo collection. Is the issue that i am using the registerHelper function incorrectly? Should i be using some other function?
Thanks in advance.
There is typo in your helper name
Template.registerHelper('tasks', function () {
return tasks.find({});
})
};
tasks not task
Your helper is registered with the same name as your template. It should be just 'task'. Template.registerHelpers should be Template.registerHelper
if (Meteor.isClient) {
// This code only runs on the client
Template.registerHelper('task', function () {
return Tasks.find({});
})
};
I'm still new to Meteor. I'm creating a Meteor JS project and one of the central features of it is image upload or more like a featured image upload. The upload works fine and after clicking on submit it will show on my <div class="viewing">. The problem occurs when you restart Meteor. The image will be deleted and thus no image is displayed by the time I run the program.
Here's my code:
The HTML:
<body>
{{> viewPost}}
<h1>Welcome to Meteor!</h1>
{{> addPost}}
</body>
<template name="addPost">
<form class="main-form">
<input type="text" name="title"/>
<br><br>
<input type="file" name="imgUp" class="fileIn"/>
<br><br>
<button>Submit</button>
</form>
</template>
<template name="viewPost">
{{#each images}}
<div class="viewing">
<img src="{{this.url store='images'}}"/>
</div>
{{/each}}
</template>
JS:
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images",{path: "~/uploads"})],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
if (Meteor.isClient) {
Template.addPost.events({
'submit .main-form': function(event, template){
var title = event.target.title.value;
event.preventDefault();
var fileObj = template.find('input:file');
Images.insert(fileObj.files[0], function (err,fileObj){});
}
});
Template.viewPost.helpers({
images: function(){
return Images.find({});
}
});
}
Please tell me what I am doing wrong here. Any help would be great! I've been looking for a way to solve this for a few days already.
I'm having issues finding a way to update the UI AFTER adding to a collection. So in the example below after you click the button and add to the collection an additional input is added to the DOM. All good, but i'd like to find a way to target the new input element and preferably give it focus in addition to CSS. Unfortunately I can't find any info that helps solve this AFTER the DOM's been updated. Any ideas? Thanks
<body>
{{> myTemplate}}
</body>
<template name="myTemplate">
{{#each myCollection}}
<input type="text" value="{{name}}"><br>
{{/each}}
<br>
<button>Click</button><input type="text" value="test" name="testBox">
</template>
test = new Meteor.Collection("test");
if (Meteor.isClient) {
Template.myTemplate.rendered = function()
{
console.log("rendered");
this.$('input').focus()
}
Template.myTemplate.helpers({
'myCollection' : function(){
var testCollection = test.find({});
console.log("helpers");
return testCollection;
}
});
Template.myTemplate.events({
'click button': function(event){
event.preventDefault();
var val = $('[name="testBox"]').val();
console.log("events");
return test.insert({name: val});
}
});
}
Turn what you're adding into a template and call that template's rendered to set the needed css or do whatever transforms are needed.
HTML:
<body>
{{> myTemplate}}
</body>
<template name="item">
<input type="text" value="{{name}}"><br>
</template>
<template name="myTemplate">
{{#each myCollection}}
{{> item this}}
{{/each}}
<br>
<button>Click</button><input type="text" value="test" name="testBox">
</template>
JS:
test = new Meteor.Collection("test");
if (Meteor.isClient) {
Template.myTemplate.onRendered(function() {
console.log("rendered");
this.$('input').focus()
});
Template.myTemplate.helpers({
'myCollection' : function(){
var testCollection = test.find({});
console.log("helpers");
return testCollection;
}
});
Template.myTemplate.events({
'click button': function(event){
event.preventDefault();
var val = $('[name="testBox"]').val();
console.log("events");
test.insert({name: val});
}
});
Template.item.onRendered(function() {
this.$('input').focus();
}
}
On a side note, you should use onRendered instead of rendered as the latter has been deprecated for the former.
Do it inside of your myCollection helper function. Use jquery to target the last input in your template and focus it, add css. Meteor's template helpers are reactive computations based on the DOMs usage of their reactive variables, so it will run each time the DOM updates based on your collection.
One template have button and another template have contains one text field.When ever button clicked that text filed append to the button template at the same time not remove the previous text fields that means the button clicked in 4 times 4 text fields add to the button template.
See the following code :
HTML Code :
<head>
<title>hello</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
<template name="hello">
Add Text Fields here :
<button>add another text box</button>
</template>
<template name="home">
<input type="text" id="name" />
</template>
JS Code :
if (Meteor.isClient) {
Template.hello.events({
'click button': function () {
//Here to write append logic
}
});
}
I didn't get any idea about this.So please suggest me what to do for this?
Use a client side only collection. Clicking adds a new record. Then in home template you loop on this. new Meteor.Collection(null) the null will tell it that it is local only and won't actually create the collection in the MongoDB.
if (Meteor.isClient) {
var buttonClicks = new Meteor.Collection(null),
clickCounter = 0;
Template.hello.events({
'click button': function () {
buttonClicks.insert({click: clickCounter++});
}
});
Template.home.helpers({
clicks: function () {
return buttonClicks.find({});
}
});
}
<template name="home">
{{#each clicks}}
<input type="text" id="name_{{click}}" />
{{/each}}
</template>
I'm using Meteor and having an issue where my content is being re-rendered when I don't want it to.
I have my main content wrapped in a currentUser if statement which I feel is fairly standard.
{{#if currentUser}}
{{> content}}
{{/if}}
The problem with this is my content template is being re-rendered when I update my user object. Is there any way around this? I don't reference users anywhere inside the content template.
Thank you!
Here's a sample app to replicate my problem:
HTML
<head>
<title>Render Test</title>
</head>
<body>
{{loginButtons}}
{{> userUpdate}}
{{#if currentUser}}
{{> content}}
{{/if}}
</body>
<template name="userUpdate">
<p>
<input id="updateUser" type="button" value="Update User Value" />
User last update: <span id="lastUpdated">{{lastUpdated}}</span>
</p>
</template>
<template name="content">
<p>Render count: <span id="renderCount"></span></p>
</template>
JavaScript
if (Meteor.isClient) {
Meteor.startup(function() {
Session.set("contentRenderedCount", 0);
});
Template.content.rendered = function() {
var renderCount = Session.get("contentRenderedCount") + 1;
Session.set("contentRenderedCount", renderCount);
document.getElementById("renderCount").innerText = renderCount;
};
Template.userUpdate.events = {
"click #updateUser": function() {
Meteor.users.update({_id: Meteor.userId()}, {$set: {lastActive: new Date()}});
}
};
Template.userUpdate.lastUpdated = function() {
return Meteor.user().lastActive;
};
}
if (Meteor.isServer) {
Meteor.users.allow({
'update': function () {
return true;
}
});
}
Update:
I should've explained this example a little. After creating a user, clicking the Update User Value button, causes the render count to increment. This is because it's wrapped in a {{#if currentUser}}. If this is if is removed, you'll notice the render count remains at 1.
Also, you'll need to add the accounts-ui and accounts-password packages to your project.
Meteor will re-render any template containing reactive variables that are altered. In your case the {{currentUser}} is Meteor.user() which is an object containing the user's data. When you update the users profile, the object changes and it tells meteor to re-calculate everything reactive involving the object.
We could alter the reactivity a bit so it only reacts to changes in whether the user logs in/out and not anything within the object itself:
Meteor.autorun(function() {
Session.set("meteor_loggedin",!!Meteor.user());
});
Handlebars.registerHelper('session',function(input){
return Session.get(input);
});
Your html
{{#if session "meteor_loggedin"}}
{{> content}}
{{/if}}