I'm following a Meteor tutorial, following it step by step and I have run into two issues:
1) when I call the {{> message}} between {{#each messages}} and {{/each}}, my "check if it works" doesn't show up at all. When I call the {{> message}} anywhere else, my "check if it works" shows up!
{{messages}}
<template name="messages">
<h3>message list</h3>
{{#each messages}}
{{> message}} <!--echo of message template-->
{{/each}}
</template>
<template name="message">
<h4>check if it works</h4> <!--didn't show up on page-->
<p>{{name}}: {{message}}</p>
</template>
2) Also none of my Javascript works at all.
I type in 'Messages.insert({ name: 'Eunice', message: 'hello world', time: 10})' to the console. and it is supposed to have Eunice: hello world pop up, sorted by time.
Messages = new Meteor.Collection('messages');
if (Meteor.is_client){
Template.messages.messages = function () {
return Messages.find({}, { sort: {time: -1} });
};
}
I'm usually a good de-bugger, so I don't know where I made a mistake. So I probably misunderstood how something works going from console to collections to templates. Thanks!
Your if check is incorrect
if(Meteor.is_client) {
}
Should be
if(Meteor.isClient) {
}
Related
I am using package aslagle:reactive-table
I want to pass an argument to the collection option of the reactive table
I have checked this also Meteor Reactive Table Helper Arguments but the comments on the post didn't help.
Html Code:
{{#each staffCode}}
{{> reactiveTable collection=collectionDetails settings=settingsResult}}
{{/each}}
Helper:
collectionDetails: function(staffCode){
return someCollection.find({staff_code: staffCode});
},
settingsResult: function(){
return {
rowsPerPage: 20,
showFilter: false,
showNavigation: 'auto',
fields: [
{
key: 'some_key', label: 'Some Label' ,
}
]
}
}
So far I tried putting
{{#each staffCode}}
{{> reactiveTable collection=collectionDetails ../code settings=settingsResult}}
{{/each}}
But this doesn't work and gives the following error in the terminal
Can't have a non-keyword argument after a keyword argument
Those who have the same issue, I have solved the problem, here's the way I approached it.
{{#each staffCode}}
{{#with collectionDetails code}}
{{> reactiveTable collection=this settings=settingsResult}}
{{/with}}
{{/each}}
I'm very new to Meteor (started yesterday) so bear with me.
I've got the following to try and get some messages from the server:
var messages = new Mongo.Collection('messages');
if (Meteor.isServer) {
//Initial first few messages
Meteor.publish("messages", function () {
return messages.find({}, {sort: {createdAt : -1}, limit: 2, reactive : false});
});
}
And then a helper for the template:
Template.card.helpers({
messages: function () {
return messages.find({});
}
});
Template:
<div class="messages-slider">
{{#each messages}}
{{> message}}
{{/each}}
</div>
I'm trying to get the first couple of messages and keep them static in the DOM, basically - however, with the above code the template updates with the collection regardless. How do I fix it?
The reactive option of find is client-only. Use it in your helper:
Session.set('ready', false);
Meteor.subscribe('messages', { onReady: function() {
Session.set('ready', true);
}});
Template.card.helpers({
messages: function () {
if (Session.get('ready')) {
return messages.find({}, {reactive: false});
}
}
});
With reference to Christian's answer:
I think you could probably solve the rendering-before-the-subscription-is-ready issue by wrapping the template in {{#if Template.subscriptionsReady}] so it won't render until the subscription is loaded. No need for Session variables in that case. For example:
Template.card.onCreated(function(){
var instance = this;
instance.autorun(function() {
instance.subscribe('messages');
});
});
Template.card.helpers({
messages: function() {
messages.find({},{reactive:false});
}
});
Template:
<template name="card">
{{#if Template.subscriptionsReady}}
<div class="messages-slider">
{{#each messages}}
{{> message}}
{{/each}}
</div>
{{/if}}
</template>
I am currently trying to have 3 separate templates that the user can switch between by clicking on one of 3 buttons. By using a session variable ('currentContent'), 3 buttons and 3 templates I cannot see what's going wrong with my current code.
In my javascript:
Template.priority.helpers({
expensesbtn:function(){
return Session.get('currentContent') ==='expenses'?true:false;
},
custombtn:function(){
return Session.get('currentContent') ==='cexpenses'?true:false;
},
incomebtn:function(){
return Session.get('currentContent') ==='earning'?true:false;
},
});
Template.priority.events({
"click #expensesbtn":function(event, template){
Session.set('currentContent', 'expenses')
},
"click #custombtn":function(event, template){
Session.set('currentContent', 'cexpenses')
},
"click #incomebtn":function(event, template){
Session.set('currentContent', 'earning')
}
});
and then in my html:
{{>priority}}
{{#if cexpenses}}
{{> cexpenses}}
{{/if}}
{{#if expenses}}
{{> expenses}}
{{/if}}
{{#if earning}}
{{> earning}}
{{/if}}
Any help with this would be greatly appreciated. Thanks!
#Sindis is right, your helper names must match what you are calling in your templates. But another problem is that while the conditionals aren't inside a template named priority, your helpers are attached to the priority template, so they wouldn't be recognized even if the names match. You can fix this by putting everything inside the priority template and separating the buttons out into a separate sub-template if that is your intention.
You can also make your code much more elegant and DRY by using only one session variable chosenTemplate and only one helper and avoiding repeating all those conditionals. Then use Meteor's Template.dynamic feature to display the correct template. Here is an example solution below. Make a new template called templateControl and place the buttons inside it. Then place everything inside the priority template.
<template name="priority">
{{> templateControl }}
{{> Template.dynamic template=chosenTemplate }}
</template>
<template name="templateControl">
{{#each buttons}}
<button id="{{ id }}" class="chose-template">{{ label }}</button>
{{/each}}
</template>
Template.templateControl.helpers
buttons: [
{ id: 'incomebtn', label: 'Income' },
{ id: 'expensesbtn', label: 'Expenses' },
{ id: 'custombtn', label: 'Custom' }
]
Template.templateControl.events
'click .chose-template': function(e, t) {
Session.set('chosenTemplate', this.id);
}
Template.priority.helpers
chosenTemplate: function(e, t) {
return Session.get('chosenTemplate');
}
Then be sure to give the three templates you switch between names corresponding to the template ids set in the chosenTemplate Session variable!
Hope this helps.
Your helpers have to be the same when you use them in HTML, so your js should look like:
Template.priority.helpers({
expenses: function(){
return Session.get('currentContent') === 'expenses';
},
cexpenses: function(){
return Session.get('currentContent') === 'cexpenses';
},
earning: function(){
return Session.get('currentContent') === 'earning';
}
});
I have a template in wish I have 2 components that represents different Models. I need to create a model that contains both datas, for each component. If I have only one model everything works fine, but when I add other one, then this error happens in the console.
Error while processing route: events record is undefined ember$data$lib$system$store$finders$$_find/</<#http://localhost:1361/test/frontend/bower_components/ember-data/ember-data.prod.js:7475:11
Backburner.prototype.run#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:222:18
ember$data$lib$system$store$$Store<._adapterRun#http://localhost:1361/test/frontend/bower_components/ember-data/ember-data.prod.js:13133:16
ember$data$lib$system$store$finders$$_find/<#http://localhost:1361/test/frontend/bower_components/ember-data/ember-data.prod.js:7470:1
tryCatch#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:53070:14
invokeCallback#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:53085:15
publish#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:53053:9
#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:31253:7
Queue.prototype.invoke#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:901:9
Queue.prototype.flush#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:965:11
DeferredActionQueues.prototype.flush#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:765:11
Backburner.prototype.end#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:158:9
Backburner.prototype.run#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:226:13
run#http://localhost:1361/test/frontend/bower_components/ember/ember.prod.js:19151:12
ember$data$lib$adapters$rest$adapter$$RestAdapter<.ajax/</hash.success#http://localhost:1361/test/frontend/bower_components/ember-data/ember-data.prod.js:1728:15
n.Callbacks/j#http://localhost:1361/test/frontend/bower_components/jquery/dist/jquery.min.js:2:26920
n.Callbacks/k.fireWith#http://localhost:1361/test/frontend/bower_components/jquery/dist/jquery.min.js:2:27738
x#http://localhost:1361/test/frontend/bower_components/jquery/dist/jquery.min.js:4:11251
.send/b/<#http://localhost:1361/test/frontend/bower_components/jquery/dist/jquery.min.js:4:14765
The route of the template that contains the components is:
App.EventsRoute = Ember.Route.extend({
model: function()
{
return Ember.RSVP.hash({
event: this.store.find('event'),
featured: this.store.find('event', 'featured')
});
}
});
Here is my template:
<script type="text/x-handlebars" id="events">
<div class="col-xs-8 pull-left">
{{#each event as |event|}}
{{#event-box event=event}}{{/event-box}}
{{else}}
no events
{{/each}}
...
{{#each featured as |highlight|}}
{{#highlight-event hlevent=highlight}}
{{/highlight-event}}
{{else}}
No Highlights
{{/each}}
...
</script>
Does anyone knows why this error happens and what can I do to solve it?
this.store.find('event', 'featured') is invalid.
Also, find is deprecated.
With the latest Ember Data, you should use store.query().
You'd probably use it like
this.store.query('event', {featured: true})
or
this.store.query('event', {filter: 'featured'})
You'll need to adjust your adapter accordingly. Something like:
urlForQuery: function(query, modelName) {
if (query && query.featured === true) {
delete query.featured;
return this._buildURL(modelName, 'featured');
}
return this._super(query, modelName);
}
This should generate an URL like http://..../events/featured.
I have an Ember.js (1.0.0) Application for which I am trying to implement the built-in Ember.Select view.
This piece of the application shows three lists of tasks: inProgress, completed, and unassigned. The user can filter the tasks shown by their corresponding project. This is where the Ember.Select view comes in. However, when I load the route, Ember barks at me about the type of value I am giving it:
Assertion failed: The value that #each loops over must be an Array. You passed projects.all
Uncaught TypeError: Object projects.all has no method 'addArrayObserver'
Uncaught Error: Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.
I have been wrestling with this for hours, trying different permutations of the code below - and I know I must be missing something obvious, because it just can't be this difficult to get such a simple component to work properly. Hoping you guys can point me in the right direction.
Here is my Route:
Bee.TasksIndexRoute = Bee.Auth.Route.extend
setupController: (ctrl) ->
# get tasks
Bee.Auth.send
url: Bee.endpoint "/tasks"
.done (tasks) ->
ctrl.set "tasks.all", tasks
# get projects
Bee.Auth.send
url: Bee.endpoint "/projects"
.done (projects) ->
ctrl.set "projects.owned", projects.owned
ctrl.set "projects.participating", projects.participating
ctrl.set "projects.all", projects.owned.concat projects.participating
Here is my Controller:
Bee.TasksIndexController = Ember.ObjectController.extend
project: null
content:
tasks:
all: []
inProgress: []
completed: []
unassgined: []
projects:
all: []
owned: []
participating: []
visible: (->
ctrl = #
# filter tasks here
).property "project"
Here is my Template:
<script type="text/x-handlebars" id="tasks/index">
<div class="center-pane">
<div class="top_options">
<div class="project_filter">
<strong>Viewing: </strong>
{{view Ember.Select
content=projects.all
optionValuePath='content._id'
optionLabelPath='content.title'
value=project
prompt='All Tasks'
}}
</div>
<strong class="gold-gradient option_button">
{{#link-to 'tasks.create' classNames='new_task'}}Create Task{{/link-to}}
</strong>
</div>
<div class="col3">
<div class="col-header in-progress light-gradient">
<h3>In Progress</h3>
</div>
<div id="tasks_active_list">
{{#if visible.inProgress.length}}
<ul>{{#each visible.inProgress}}{{view Bee.TaskListView}}{{/each}}</ul>
{{else}}
<p class="no_projects">None</p>
{{/if}}
</div>
</div>
<div class="col3">
<div class="col-header completed light-gradient">
<h3>Completed</h3>
</div>
<div id="tasks_closed_list">
{{#if visible.completed.length}}
<ul>{{#each visible.completed}}{{view Bee.TaskListView}}{{/each}}</ul>
{{else}}
<p class="no_projects">None</p>
{{/if}}
</div>
</div>
<div class="col3">
<div class="col-header unassigned light-gradient">
<h3>Unassigned</h3>
</div>
<div id="tasks_unassigned_list">
{{#if visible.unassigned.length}}
<ul>{{#each visible.unassigned}}{{view Bee.TaskListView}}{{/each}}</ul>
{{else}}
<p class="no_projects">None</p>
{{/if}}
</div>
</div>
</div>
</script>
Any insight will be much appreciated. I do know that the Ember.Select is the culprit, since when I replace it with a simple:
<select>
{{#each projects.all}}
<option value="{{_id}}">{{title}}</option>
{{/each}}
</select>
... it renders fine - however I need to use the Ember.Select so I can bind the value to the project property on the TasksIndexController - since I will use that as an observable for firing the visible function.
try setting projects.all to null up front. maybe ember select has an issue with the pojo default array on the class.
Bee.TasksIndexController = Ember.ObjectController.extend
project: null
content:
tasks:
all: []
inProgress: []
completed: []
unassgined: []
projects:
all: null
owned: []
participating: []
visible: (->
ctrl = #
# filter tasks here
).property "project"
setupController: (ctrl) ->
# get tasks
Bee.Auth.send
url: Bee.endpoint "/tasks"
.done (tasks) ->
ctrl.set "tasks.all", tasks
# get projects
Bee.Auth.send
url: Bee.endpoint "/projects"
.done (projects) ->
ctrl.set "projects.owned", projects.owned
ctrl.set "projects.participating", projects.participating
ctrl.set "projects.all", projects.owned.concat projects.participating
Here's a simplified example: http://emberjs.jsbin.com/aletIyU/3/edit