• Meteor

Make A Data Source Nonreactive

From the class:  Tracker

Sometimes we want to make our reactive data source not reactive temporarily and one of the ways we can do that is by calling the non-reactive function of Tracker. So this will temporarily disable a reactive data source so that our function never re-runs again as a result of the data source changing. In this lesson, I want to show you why it is that that works and I'll show you an example of how to use non-reactive.

Let's review the magic that happens when you call the get function of a reactive data source or in other words, if you just call a reactive data source function, in this case we call it get and here we are dropped in the debugger statement in the get function of our reactive data source name. And the magic happens when you call the depend method of the Tracker dependency.

In order for this to work, there has to be an active computation and remember an active computation gets set on the global variable called CurrentComputation. Let's step into the depend functions that you can be reminded of what happens there. So I'll step in and notice it's checking to see whether or not a computation was passed in, and if not, whether or not Tracker is active.

Let me make this a little larger. If it's not active, then it will just return false, so we don't need to do anything. Otherwise, it grabs the current computation that was set on the global variable.

Let me clear up the drawing here. So this is going to be the current computation and remember on the stack that there's only one current computation. So here's our stack trace, it moves up just like this, and here's where the computation gets set. So at this point, by the time we get up to this get function, what this depend method is going to do is just store away this computation here so that it can re-run that later.

And you can see that code down here. It's very similar to what we wrote when we started off building our reactive data source. So the trick here is we want to temporarily make Tracker not active, so we want to set somehow the current computation to null and so when this depend function gets called, it just returns false and doesn't store the computation.

Well, it turns out there's an easy way to do this. It's by using the non-reactive function that Meteor provides us. Let's see how that works.

I'll make the code a little bit larger because this is going to be quite a line here. The way that we can use the non- reactive function is to call Tracker non-reactive and then pass in a callback function that will get called. And so when we pass callback functions like this, by the way, it's a nice way to delay executions. So that's a pattern that you'll see again and again where we pass in a function that then Meteor can call at a later time.

So let's name this function so we can see it inside of the stack. I'm going to call it disableComputation or let's just call it computationDisabled. And this non-reactive function can return a value. So we can take this result and return it and it will be assigned to this variable called name and then we can use it just like we did before. And what this non-reactive function will do is, render this reactive data source sort of useless. It will just get the value once, but it won't track the computation and so this sayHello function will not re-run as a result of this name changing.

Let's go over to the debugger and I'll show you why this works. We're back at our debug line here. The only difference is, now we've called non-reactive and so we have an extra item in our call stack here. You can see Tracker nonreactive was called and then the computationDisabled function that we defined right here was called and then finally, we called name.get.

To get a hint at what's going on by the time we get to this function, let's step back into the call stack and see what happens when we call Tracker.nonreactive. So we can step back by clicking, which is a really useful debugging technique. We can just go back into the stack and see what's happened at a previous point. If I scroll up here, notice that the implementation of the non-reactive function is quite simple. It tracks the previous version of the previous computation by using the global variable, then it sets it to null and then calls our function.

And finally, when we get back to this point in the call stack, so it's going to call our function which will go up and when we get back to this point in the call stack, it will finally reset the computation back to the previous value. So it temporarily sets the computation to null. So by the time we get up to here, there's no active computation.

So I'm going to go ahead and go back to name.get and let's see what happens when we step into the depend function this time. Is Tracker active? It's not and so it's just going to return false and no computation gets stored on the dependency object up here.

So to prove that this works, we can go and set a bunch of values and make sure that the function doesn't actually re-run. So we'll set the name to two, and three, and so on and notice our sayHello function is no longer re-running as a result of the reactive data source changing because we rendered it non-reactive by using the non-reactive function.