Hey I am new to developing in JS and METEOR and I have a small issue. The web app I am trying to make is a simple presentation app where the contents are stored in a DB. (Im guessing there are better ways to do what im about to describe) :
Heres my presentation template in main.html
<h2 style="text-align: center;"><kbd>{{gettitle}}</kbd></h2>
<br>
<pstyle="text-align: center; font-size: 20px;">{{content}}</p>
Here is the main.js
Title = new Mongo.Collection(‘title’);
Content = new Mongo.Collection(‘content’);
slideIndex = 1;
Template.body.events({
‘keyup’(event){
if (event.key == ‘ArrowRight’) {
console.log(“You pressed Right”);
slideIndex = slideIndex + 1;
console.log(slideIndex);
} else if (event.key == 'ArrowLeft') {
console.log("You pressed Left");
slideIndex = slideIndex - 1;
console.log(slideIndex);
}
}
});
Template.presentation.helpers({
gettitle(){
// console.log(Title.findOne({slide:slideIndex}));
console.log(slideIndex);
var findTitleObj = Title.findOne({slide:slideIndex});
var titleText = findTitleObj.text;
// console.log(titleText);
return titleText;
},
content(){
//console.log(Content.findOne({slide:slideIndex}));
var findContentObj = Content.findOne({slide:slideIndex});
var contentText = findContentObj.text;
//console.log(contentText);
return contentText;
}
});
The code works as intended, initially when slideIndex is 1 it fetches the title and content. When I press the right arrow key the slideIndex is updated but the presentation template won’t update the title or content. I would have to switch between templates to see the results. Is there anyway I can fix this issue? (Im guessing its simple, do forgive me for the title if it isn’t
)
Thank you
What you want is to bind your helpers to a reactive dependency. In this case you want that dependency to be the slide index.
Easiest way is to use a ReactiveVar
instead of a plain js variable to hold the slideIndex.
First add it to your project:
$ meteor add reactive-var
Then use it in the code:
import { ReactiveVar } from 'meteor/reactive-var'; // <-- added
slideIndex = new ReactiveVar(1); // <-- changed
Template.body.events({
'keyup'(event){
if(event.key == 'ArrowRight') {
console.log(“You pressed Right”);
slideIndex.set(slideIndex.get() + 1); // <-- changed
console.log(slideIndex);
} else if (event.key == 'ArrowLeft') {
console.log("You pressed Left");
slideIndex.set(slideIndex.get() - 1); // <-- changed
console.log(slideIndex);
}
}
});
Template.presentation.helpers({
gettitle() {
// console.log(Title.findOne({slide:slideIndex}));
console.log(slideIndex);
var findTitleObj = Title.findOne({ slide: slideIndex.get() }); // <-- changed
var titleText = findTitleObj.text;
// console.log(titleText);
return titleText;
},
content() {
var findContentObj = Content.findOne({ slide: slideIndex.get() }); // <-- changed
var contentText = findContentObj.text;
//console.log(contentText);
return contentText;
}
});
Have a read of this section of the Client-side data with reactive stores section of the guide:
The key things being, a reactive data source used inside a helper or autorun will cause that helper or autorun to re-run automatically whenever it’s value changes. Collections are reactive by default, as are ReactiveVars and ReactiveDicts. These are the single most powerful part of Meteor’s reactivity model.
2 Likes
Thank you so much for the help. Yeah shortly after i posted this question I was able to find resources on session and reactive variables and ended up using the session variables.
1 Like