Show current date in meteor [closed] - meteor

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 template reactive?

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'}});
}
});
}

How to perform Meteor.call on Session variable change

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);
});

Setting the reactive data source from Route (Iron Router) is breaking reactivity

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.

Session.set vs changing the variable

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');
});

Meteor, How can I display a url query in the client?

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

Resources