[Solved] How to remove dependency in Tracker

The following code loops

const route = new ReactiveVar (['login'])

Tracker.autorun(() => {
  const u = Meteor.userId()
  if (!u) {
     console.log("before", route.get())
     route.set(['login'])
     console.log("after", route.get())
  }
 })

With the following message

before ["login"]
after ["login"]
before ["login"]

This is due to ReactiveVar using pointer equality by default, the reactive var doesn’t recognize the array is already [‘login’] and updates, which triggers the autorun. Simple fix is to provide a custom equality function that computes structural equality.

const array_eq = (a, b) => {
  if (a == null && b == null) return true
  if (!a || !b) return false
  if (a.length != b.length) return false
  for (let i = 0, leni = a.length; i < leni; i++) if (a[i] != b[i]) return false
  return true
}

That said, is it possible to prevent the autorun from depending on the reactive variable ? That is, to only trigger when there is a change in Meteor.userId() and not in routes ?

http://docs.meteor.com/#/full/tracker_nonreactive

My understanding is that Tracker.nonreactive eliminates ALL dependencies. Here we want to recompute when Meteor.userId() changes but not when the reactive variable Routes changes.

You make the reactive call that you don’t want to track inside Tracker.nonreactive, the rest outside of it.

Tracker.autorun(function(){
  var userId = Meteor.userId(); // Depend on user id.
  var routeVal;
  Tracker.nonreactive(function() {
    routeVal = route.get(); // Don't depend on route
  });
  // Do something with routeVal & userId
})
2 Likes

Cool ! That’s what I missed.