Simple JS/Meteor question

#1

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 :slight_smile: )

Thank you

#2

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
#3

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