Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I want to display the current date. I have written the following code but it does not diplay the value of value variable.
<head>
<title>my_first_app</title>
</head>
<body>
<h1>Hello from Pakistan</h1>
{{> hello}}
{{> date}}
</body>
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</template>
<template name="date">
<p>The time now is {{value}}.</p>
</template>
JS:
if (Meteor.isClient) {
// counter starts at 0
Session.setDefault('counter', 0);
Template.hello.helpers({
counter: function () {
return Session.get('counter');
}
});
Template.hello.events({
'click button': function () {
// increment the counter when button is clicked
Session.set('counter', Session.get('counter') + 1);
}
});
var value = new Date();
Template.date.helpers(value);
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
If you want to show current time you can write something like below
Template.date.helpers({
value: function () {
return Session.get('currentDate');
}
})
Template.date.onRendered(function(){
// this will update date every second, if you want update for every minute do 60 * 1000
Meteor.setInterval(function () {
Session.set(currentDate, new Date());
}, 1 * 1000);
})
template.date.helpers require an object, with methods for each returnable outcome. Exactly as you have done with the counter helper on the hello template:
Template.date.helpers({
value: function () {
return new Date();
}
});
Related
Why isn't this reactive? And more importantly how can it be made reactive?
I'd like the data to be saved in Mongo and used in the template. I could use a ReactiveVar or ReactiveDict. Do I need two copies of the data?
Doesn't Suspects.findOne('bruce') return a reactive object already? I tried putting the human answer directly on Bruce, but it didn't trigger an update.
The events fire, log(this) shows bruce's answer was changed, but the template doesn't re-render. What's the good way to do this?
http://meteorpad.com/pad/KoH5Qu7Fg3osMQ79e/Classification
It's Meteor 1.2 with iron:router added:
<head>
<title>test</title>
</head>
<template name="question">
{{#unless isAnswered 'human'}} <!-- :-< I'm not reacting here -->
<div>Sir, are you classified as human?</div>
<button id="no">No, I am a meat popsicle</button>
<button id="smokeYou">Smoke you</button>
{{else}}
<div> Classified as human? <b>{{answers.human}}</b></div>
{{/unless}}
</template>
And the JavaScript:
// Why isn't this reactive?
if (Meteor.isClient) {
Template.question.helpers({
isAnswered: function (question) { // :-< I'm not reactive
var suspect = Template.instance().data;
return (typeof suspect.answers[question] !== 'undefined');
}
});
Template.question.events({
'click #no': function () {
this.answers.human = "No"; // :-< I'm not reactive
console.log(this);
},
'click #smokeYou': function() {
this.answers.human = "Ouch"; // :-< I'm not reactive
console.log(this);
}
});
}
// Collection
Suspects = new Meteor.Collection('suspects');
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
Suspects.upsert('bruce', { quest: 'for some elements', answers: {}});
});
Meteor.publish('suspects', function() {
return Suspects.find({});
});
}
// Iron Router
Router.route('/', {
template: 'question',
waitOn: function() {
return Meteor.subscribe('suspects');
},
data: function() {
return Suspects.findOne('bruce');
}
});
Thanks :-)
The events are not actually updating the reactive data source (the db record). Instead of doing:
Template.question.events({
'click #no': function () {
this.answers.human = "No";
}
});
The event needs to perform a database action, either through a direct update or through a Meteor.call() to a Meteor.method. For example:
'click #no': function(){
Suspects.update('bruce', {'answers': {'human': 'no'}});
}
If you use this pattern, you will also need to set the correct allow and deny rules to permit the update from client code. http://docs.meteor.com/#/full/allow. Methods generally end up being a better pattern for bigger projects.
Also, I'm not sure off the top of my head that Template.instance().data in your helper is going to be reactive. I would use Template.currentData() instead just to be sure. http://docs.meteor.com/#/full/template_currentdata
Very close you just need to use ReactiveVar by the sound of it it pretty much explains what it's :) http://docs.meteor.com/#/full/reactivevar
and here's how to use it
if (Meteor.isClient) {
Template.question.onCreated(function () {
this.human = new ReactiveVar();
});
Template.question.helpers({
isAnswered: function (question) {
return Template.instance().human.get();
}
});
Template.question.events({
'click #no': function (e, t) {
t.human.set('No');
console.log(t.human.get());
},
'click #smokeYou': function(e, t) {
t.human.set('Ouch');
console.log(t.human.get());
}
});
}
UPDATE: if you're using a cursor I usually like to keep it on the template level not on iron router:
if (Meteor.isClient) {
Template.question.helpers({
isAnswered: function (question) {
return Suspects.findOne('bruce');
}
});
Template.question.events({
'click #no': function (e, t) {
Suspects.update({_id: ''}, {$set: {human: 'No'}});
},
'click #smokeYou': function(e, t) {
Suspects.update({_id: ''}, {$set: {human: 'Ouch'}});
}
});
}
Here is what I have:
Templates:
<body>
{{> resultSession}}
{{> resultMethod}}
</body>
<template name="resultSession">
<button>Click me</button>
<p>Session.get('length') returned {{returned}}</p>
</template>
<template name="resultMethod">
<p>Meteor.call returned {{returned}}</p>
</template>
Client-side:
Template.resultSession.events({
'click button': function () {
Session.set('length', Math.floor((Math.random() * 20) + 1));
}
});
Template.resultSession.helpers({
returned: function () {
return Session.get('length');
}
});
Template.resultMethod.helpers({
returned: function() {
Meteor.call('returnArray', Session.get('length'), function (err, res) {
return res.length;
});
}
});
Server-side:
Meteor.methods({
'returnArray': function (length) {
var arr = [];
arr[length - 1] = 0;
return arr;
}
});
TL;DR
You can look at code and play with it here http://meteorpad.com/pad/AkBZq4ZFjJuQuzztz/Meteor.call-on-Session-change
As you can see, my method accepts number and returns the array with length equal to number.
The question is how can I make Meteor.call fire each time Session variable changes?
P.S. Values are returned to two different templates on purpose
Your reactive code is working perfectly.
If you put a console.log in the Meteor.call you will see that the correct answer is coming back from the server.
Template.resultMethod.helpers({
returned: function() {
Meteor.call('returnArray', Session.get('length'), function (err, res) {
console.log('it came back ' + res.length);
return res.length;
});
}
});
I have put a Session variable into the return from the server, so now you can see that your reactive code works very simply - no need for complicated autorun stuff.
<template name="resultMethod">
<p>Meteor.call returned {{returned}}</p>
</template>
Then in the resultMethod helper:
Template.resultMethod.helpers({
returned: function() {
Meteor.call('returnArray', Session.get('length'), function (err, res) {
Session.set('fromServer', res.length + '');
});
return Session.get('fromServer');
}
});
Like #saimeunt said, use Tracker.autorun
Templates:
<body>
{{> resultSession}}
{{> resultMethod}}
</body>
<template name="resultSession">
<button>Click me</button>
<p>Session.get('length') returned {{returned}}</p>
</template>
<template name="resultMethod">
<p>Meteor.call returned {{returned}}</p>
</template>
And code:
Template.resultMethod.rendered = function() {
this.autorun(function (){
Meteor.call('returnArray', Session.get('length'), function (err, res) {
Session.set('result', res);
});
});
}
Template.resultSession.helpers({
returned: function () {
return Session.get('length');
}
});
Template.resultMethod.helpers({
returned: function() {
return Session.get('result');
}
});
Autorun inside rendered stops when the template is not rendered
You could simply refactor your code to call the Meteor method on click event ?
Template.resultSession.events({
'click button': function () {
var length = Math.floor((Math.random() * 20) + 1);
Session.set('length', length);
Meteor.call('returnArray', length, function (err, res) {
Session.set('result', res.length);
});
}
});
Template.resultSession.helpers({
returned: function () {
return Session.get('length');
}
});
Template.resultMethod.helpers({
returned: function() {
return Session.get('result');
}
});
You could also use Tracker.autorun to track modifications of your Session variable and rerun arbitrary code.
Tracker.autorun(function(){
var length = Session.get("length");
console.log("length new value =", length);
});
I have following code in the Router (Iron Router)
Router.map( function () {
this.route('hello',{path:'/hello',
onBeforeAction: function(){
console.log("QBConnected"+this.params.qbconnected);
Session.set("QBCONNECTED",this.params.qbconnected);
}
});
});
Following code in test.html
<template name="hello">
{{#if QBCONNECTED}}
<h1>Hello World if value={{QBCONNECTED}}</h1>
{{else}}
<h1>Hello World else value={{QBCONNECTED}}</h1>
{{/if}}
{{greeting}}
<input type="button" value="Click" />
</template>
Following code in test.js
if (Meteor.isClient) {
//Session.setDefault('QBCONNECTED',false);
Template.hello.greeting = function () {
return "Welcome to test.";
};
Template.hello.events({
'click input': function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
Template.hello.QBCONNECTED=function(){
console.log(Deps.active+"get QBCONNECTED called"+Session.get('QBCONNECTED'));
return Session.get('QBCONNECTED');
};
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
when I try to run this with the URL http://x.x.x.x:3000/hello?qbconnected=true
I see the string "Hello World if value=true" as expected
But when I try the url http://x.x.x.x:3000/hello?qbconnected=false, I see the string
Hello World if value=false. Can anyone please explain why it is entering the if block when the value of QBCONNECTED is false?
When I try to set the value manually from browser console by "Session.set("QBCONNECTED",true)" it prints "Hello World if value=true" as expected but when I try "Session.set("QBCONNECTED",false)" it prints "Hello World else value= " , can any one explain why QBCONNECTED is loosing it's value when set to false ?
This is happening because false from your querystring gets evaluated to the "false" string and not false boolean value as you might have expected.
I have this template:
<body>
{{> hello}}
</body>
<template name="hello">
{{greeting}}
</template>
And this is the controller:
if (Meteor.isClient) {
Template.hello.greeting = "Hi";
Meteor.setInterval(function() {
Session.set("greeting", Values.findOne({}).value.toString());
console.log(Values.findOne({}).value);
}, 1000);
}
On the console I'm getting the value in the collection Values. However, when I Session.set it to greeting, the variable isn't updated on the HTML page. The "Hi" I default it to just stays there while every second I get the value that should be in it on the console.
Try doing this:
Template.hello.greeting = function () {
return Session.get('greeting');
});
I am new to meteor, but it seems like this should be simple. I want to create a page that pulls a get variable down and displays it on the client
ex: www.example.com?yourname=bob
and the page would display
bob
I feel like this should be easy, but so far have not been able to do it. I created an call when the client loads that asks for the info, but it doesn't work on the first load for some reason. On subsequent loads it does.
<head>
<title>Page Chat</title>
</head>
<body>
<div id="wrapper">
{{> name}}
</div>
</body>
<template name="name">
{{name}}
<br />
<input type="button" value="Click" />
</template>
js code
if (Meteor.isClient) {
Meteor.startup(function(){
Meteor.call("getData", function(error, result){
if(error){
Session.set("name", "bob");
}
else{
Session.set("name", result.name);
}
});
});
Template.name.name = function(){
return Session.get("name");
};
Template.name.events({
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
}
if (Meteor.isServer) {
var connect = Npm.require('connect');
var app = __meteor_bootstrap__.app;
var post, get;
app
// parse the POST data
.use(connect.bodyParser())
// parse the GET data
.use(connect.query())
// intercept data and send continue
.use(function(req, res, next) {
post = req.body;
get = req.query;
return next();
});
Meteor.startup(function () {
});
Meteor.methods({
getData: function() {
return get;
},
postData: function(){
return post;
}
});
}
If possible I would like to share the data on the initial page load, it seems like a waste to create an separate page load to get information thats already there when the page is first loading.
It might be easier to use something like meteor-router. Then you could do
server side js:
Meteor.Router.add('/something', function() {
return this.params.yourname;
});
So if you visited example.com/something?yourname=Bob you would get back Bob.
Be careful when displaying something directly to the client from a querystring/input parameter as if you don't check it before it could be used for XSS.
Original url is "http://example.com:3000/test?xyz", you can use any one below
Router.current().request.url
"http://example.com:3000/test?xyz"
Router.current().url
"http://example.com:3000/test?xyz"
Router.current().originalUrl
"http://example.com:3000/test?xyz"
Router.current().route._path
"/test"
Router.current().route.getName()
"test"
https://github.com/iron-meteor/iron-router/issues/289