[SOLVED] What if a function doesn't always return the result of a reactive computation?


#1

So, for example, what if I have a function like

function sometimesReactive() {
  if (Math.floor(Math.random()*2)) {
    return Session.get('something') // reactive
  }
  else {
    return Math.floor(Math.random()*2)
  }
}

Does the function still get executed every time the value of Session.get('something') changes?


#2

Aha, it’s not! I tried

    Template.foos.helpers({
        foos: function () {
            if (Math.floor(Math.random()*2)) {
                return fooCollection.find()
            }
            else {
                return [{"name": Math.floor(Math.random()*2), "foo": "3,126", "bar": "Monroe Co.", "baz": "Friend"}]
            }
        }
    })

and what seems to happen is that the result is cached, and is only re-evaluated if the result was reactive. The conditional logic inside the function isn’t re-executed.

I can tell because

  • I can restart the app and each time the view randomly shows one of the two outcomes.
  • If the view ends up with the hard-coded state, then if I update any data in Mongo, the view doesn’t ever go back to the other possible state no matter how many times I try modifying data (using msavin:mongol makes this easy).
  • But if after restarting the app the view ends up with the result of the reactive Session.get value, then every time I modify data the view gets updated

so this obviously means that reactivity only happens based on whether the returned value was a reactively-computed value or not.

Replacing

            if (Math.floor(Math.random()*2)) {

with

            Session.set('random', Math.floor(Math.random()*2))
            if (Session.get('random')) {

also doesn’t work, I suppase because it knows it’s the same exact logic masked in a Session variable.

BUT!

Doing something like

    setInterval(function() {
        Session.set('random', Math.floor(Math.random()*2))
    }, 1000)

    Template.foos.helpers({
        foos: function () {
            if (Session.get('random')) {
                return fooCollection.find()
            }
            else {
                return [{"name": Math.floor(Math.random()*2), "foo": "3,126", "bar": "Monroe Co.", "baz": "Friend"}]
            }
        }
    })

does work!

What magic wizardry!