I'm having an issue with a Session variable that I am using to keep track of a search query when using alongside the Meteor Typeahead package.
When I log the variable in the console the last character displays but when I output my helper in the template that Typeahead calls, it omits the last character.
My event:
Template.bookSearchForm.events
'keyup .typeahead': (e) ->
bookVal = e.target.value
Session.set 'bookSearchValue', bookVal
My helper:
Template.searchNoItems.helpers
bookSearchValue: ->
return Session.get 'bookSearchValue'
My template:
<template name="searchNoItems">
<div class="search-no-results">
<span class="lookupBook">Search for {{ bookSearchValue }}</span>
</div> <!-- /.search-no-results -->
</template>
Any ideas would be greatly appreciated. Just to confirm, the console is spitting out the full query eg: "My Query" whereas in the helper it's only outputting: "My Quer".
Thanks for taking a look.
use this {{{ bookSearchValue }}} notice it's 3 curly braces
Handlebars/Spacebars HTML-escapes values returned by a
{{expression}}. If you don't want to escape a value, use the
"triple-stash", {{{
Related
Following an example from a book, I have in my .js file
lists = new Mongo.Collection("Lists");
if (Meteor.isClient) {
Template.categories.helpers ({
'Category': function(){
return lists.find({}, {sort: {Category: 1}});
}})
and in my html file:
<body>
<div id="categories-container">
{{> categories}}
</div>
</body>
<template name="categories">
<div class="title">my stuff</div>
{{#each lists}}
<div>
{{Category}}
</div>
{{/each}}
</template>
I have input data this data into lists which uses Category for a field using the console:
> lists.insert({Category:"DVDs", items: {Name:"Mission Impossible"
,Owner:"me",LentTo:"Alice"}});
> lists.insert({Category:"Tools", items: {Name:"Linear Compression
Wrench",Owner:"me",LentTo: "STEVE"}});
but it doesn't output the data.
I think the issue lies in the context of your {{#each}}, you seem to be attempting to access the mongo collection itself rather specific fields through a helper function.
Check out this tutorial on spacebars, it’s a pretty good read http://meteorcapture.com/spacebars/ and also the Meteor Docs section http://docs.meteor.com/#/full/livehtmltemplates. I'm fairly new to Meteor myself but hope that helps.
In your example, you use name Category for 2 different things.
It is the name of template helper function that return an array of list items.
and it is the name of a field item inside your list.
Do the {{#each Category}} to run on the array returned by the helper
Inside the each, you should access the {{Category}} or {{item}} list items
You just need to call your helper lists instead of Category and your code will work:
Template.categories.helpers({
lists: function () {
return lists.find({}, {sort: {Category: 1}});
}
});
{{#each lists}} means: Iterate over a collection cursor (the result of a find) or an array which we get by calling the helper lists. The naming here is somewhat confusing because lists also happens to be the name of the collection your are iterating over.
Inside of the each, the context is a lists document. Each document contains a Category field, which you are outputting inside of a div.
Recommended reading:
A Guide to Meteor Templates & Data Contexts
check to run command : meteor list
it is given to you list of packages which is you used
if autopublish package not in the list you want to publish and subscribe your data here's simple example:
//in server
Meteor.publish('lists',function(){
return lists.find({}, {sort: {Category: 1}});
})
//in client
Meteor.subscribe('lists');
For More Deatails : publish subscription
First: The function in your 'categories' helper shouldn't be between quotes (not sure if that may couse problems).
Second: You are using the {{#each}} loop wrong.
You are calling the 'Lists' collection, but you should call the 'Categories' helper.
<template name="categories">
<div class="title">my stuff</div>
{{#each Category}}
<div>
{{Category}}
</div>
{{/each}}
</template>
Its very confusing your helper has the same name as the field you are calling in the #each loop.
The following calls messages when the page loads but not when a Session value is changed. Here is the template code;
<head>
<title>Your welcome to chat</title>
</head>
<body>
{{> chat}}
</body>
<template name="chat">
<div class="ui list" style='height: 100px; overflow:scroll;' id='chatHistory'>
{{> currentChatList}}
</div>
<div class="ui large icon input">
<input type="text" class="field" id="message" placeholder="Type your message here" />
<i class="comment icon"></i>
</div>
</template>
<template name="currentChatList">
{{#each messages}}
{{/each}}
</template>
Here is the code;
if (Meteor.isClient) {
Template.chat.events ({
'keydown input#message' : function (event) {
if (event.which == 13) { // 13 is the enter key event
Session.set('time', new Date());
}
}
});
Template.currentChatList.helpers({
messages : function () {
debugger;
return [];
}
});
}
debugger statement is hit when the page loads, but not when the enter key is pressed on the textbox and Session.set('time'..) is executed. I thought a Session value change would cause the template to render.
saimeunt's answer will solve you problem. Your helper at the moment doesn't access any reactive variable (Session or Collection), which means it's never executed again.
Recently more and more people prefer to use reactive-var:
The idea is that you declare a reactive variable within your JS file and then USE that reactive variable in your helper. Every time you change the variable, all helpers using this variable are re-executed.
You do not depend on the Session variable you're assigning anywhere on your code. A reactive computation such as template helpers only reruns if one of its dependent reactive data sources is modified, which is clearly not the case in your example.
Try to depend on the Session variable inside your helper code to make it re-execute whenever you press enter.
Template.currentChatList.helpers({
messages: function () {
debugger;
var time = Session.get("time");
console.log("You pressed enter at",time);
return [];
}
});
FINALLY THE ANSWER: OMG.
https://blog.meteor.com/the-meteor-chef-reactive-dict-reactive-vars-and-session-variables-971584515a27
I have tried window.someVariableThatChanges = NOT WORKING
I have tried a Session.someVariableThatChanges = NOT WORKING
REACTIVE VARIABLE -- TOTALLY WORKING.
The difference is that you need to create a Template ON CREATED event, add your variables there. Simply use this variable in your even that changes the value, and your helper reference -- it works like magic and feels soooooo goooooood.
I'm new to both meteor and JS.
I created a meteor app like this:
cd /tmp/
meteor create hello
cd hello
In hello.html I wrote this
<body>
<h1>Welcome to Meteor!</h1>
{{> t1}}
{{> t2}}
</body>
Then I added these templates:
<template name='t1'>
<span id='t1'>hello</span>
</template>
<template name='t2'>
<span id='t2'>world</span>
</template>
Then I wrote syntax inside of hello.js to get text from the DOM:
Template.t1.onRendered( function() {
mytext = $('span#t1').html() });
According to the debugger-console in my browser,
the above syntax works okay.
The debugger tells me that mytext == 'hello'
Question: How to share the mytext value with other parts of my Meteor app?
As written, mytext is stuck inside my anonymous function.
For example how would I make this call work:
$('span#t2').html(mytext)
??
You'll want to reactively watch your variable. An easy out-of-the-box solution for this is to use the Session variable. You can do it pretty easily like so:
Template.t1.onRendered( function() {
Session.set('mytext', $('span#t1').html());
});
Then in your second template, define and reference helper that returns that variable:
<!--html-->
<template name='t2'>
<span id='t2'>{{getMyText}}</span>
</template>
//js
Template.t2.helpers({
getMyText: function() { return Session.get('mytext'); }
});
The Session variable is reactive, so when the first template renders and sets the value of Session.mytext, the helper's result will be invalidated and the second template will update.
I am trying to insert various templates depending on which button is clicked. For this I created an event that sets a session variable with the id of the button.
'click .task-option-button': function (e) {
var template = e.target.id;
Session.set('addTaskTemplate', template);
console.log(template);
}
and a helper that returns the session variable
addTaskTemplate: function () {
var taskTemplate = Session.get('addTaskTemplate');
return taskTemplate;
},
and then the template gets inserted like this
{{> Template.dynamic template= "{{addTaskTemplate}}"" }}
However, clicking the button doesn't add the template. When I put
{{> Template.dynamic template= "SomeStaticTemplate" }}
it works. Also using {{addTaskTemplate}} as a normal variable in <p></p> tags works and returns the id of the button as a string. Is there anything I am missing here?
{{> Template.dynamic template= addTaskTemplate }} will do. Just remove the {{ }} brackets.
I would like to insert a string that contains a link with a helper (or is there any better option to achieve this?) in meteor blaze.
So far blaze just gives back the link as normal text with the '' tags.
Does anyone have a good solution or workaround for this?
Here is a simple example to get you started :
<template name="parent">
{{> linkTemplate linkData}}
{{#each links}}
{{> linkTemplate}}
{{/each}}
</template>
<template name="linkTemplate">
{{title}}
</template>
Links=new Meteor.Collection(null);
Links.insert({
url:"https://www.google.com",
title:"Google"
});
Template.parent.helpers({
linkData:function(){
return {
url:"https://www.google.com",
title:"Google"
};
},
links:function(){
return Links.find();
}
});
If you want to render a string in a template that happens to contain a link, you would have to provide the HTML string as in
var string="A link to Google.";
Then you can use the triple bracket syntax {{{helperReturningHTMLString}}} and it will work as expected, but I don't think it's good practice unless you're working with something like a WYSIWYG editor.