• Meteor

Working with the Reload Package

Let's take a look at the reload package. In the left in my code I've created a reference to the reload object, and that's because we haven't added this package directly to our web application. But it is available under the package name space. Over in the browser, if we look at the reload object, we can see the three methods that we're going to look at today. They're all underscore methods, which means that Meteor hasn't decided to make them public yet, but we'll look at how they work anyway.

So the three methods are _onmigrate, _migrationdata and reload. The reload function is responsible for simply reloading the browser. But it doesn't just reload the browser. It gives each package a chance to say whether or not the package is ready to do a reload. And it also does something else, which is to save away any data that packages want saved before the reload happens. So we'll look at exactly how that works, but just to get us started, let me call the reload function. And there you go. You see that the browser just reloads itself.

The _onmigrate method gives packages the chance to register a callback function that will get called before the reload happens. And that callback function can tell the reload process to continue with the reload or to stop. For example, Session uses the _onmigrate callback mechanism. So if we were to set Session somevalue, or somekey, somevalue, and then call the reload method, you can see the browser refreshes. But if I grab the somekey from Session, you see that the value is preserved across the reload.

And that method is in the middle called _migrationdata is how we are able to get data back that was preserved during a reload. So these are the three functions are we're going to look at in more detail.

Let's jump over to the code and start off by registering our own callback with _onmigrate so that we can control when the reload happens. OK, so I've called the _onmigrate function, and I've passed a callback function as a parameter. This callback function will get called with a function as its parameter, and that function is a retry function. We'll look at that in a minute. To start us off, this callback function can return false to stop the migration, or to stop the reload. Or it can return an array with true as the first value. And we'll see why it's an array a little bit later.

So just to get us started, let me refresh the browser. And if I call reload now, you can see that the browser reloads right away. And that's because our _onmigrate callback just returns an array with the value of true as the first value.

So how would we pause the migration? This part is a little bit tricky. So let's do it one step at a time. I'm going to create a variable called isready. I'm going to make it global so that we can just assign to it. Now, inside of the _onmigrate callback, what we'll do is we'll say if isready is true, we'll return true. And if it's not, we'll return false. We need to do one more thing, which is let's create a global variable for the retry function.

This is pretty confusing. So it's better, actually, to create a wrapper around this migrate function, which we'll do a little bit later. But for now, what we need to do is to store away the retry function so that we can call it later, which will cause all of these migrate callbacks to get called again. So if isready is false, what we'll do is set the retry function to the retry function that's passed into our callback. And then we can call this retry function from the console.

And then as long as isready has been set to true, the migration will continue as planned. So let's go over and refresh the browser. And we'll start this process off by calling the reload function of reload. OK, this time you can see the browser doesn't reload. And that's because our _onmigrate callback returns false. But we have a retry function now, and if we call this retry function it's going to re-run all of the _onmigrate callbacks. And so, this time if all of the packages say that they're ready to go by returning an array with true as the first value, then the migration will continue.

So before we call that function, let's set isready to true. And now, we'll call the retry function. And if you look carefully, you should see that the browser reloads.

Next, let's look at how we can save data and retrieve the data after the reload has completed. The first thing we need to do is to name this migration. And so, as a first parameter, instead of passing the callback function, I'm going to pass a name. Since we're doing this inside of our application, I'm just going to call it app. Then when we say that we're ready to migrate, the second value of the array is going to be an object of key value pairs that we want to save.

So in this contrived example, why don't I just create one property with a key of name, and a value of Chris. Now, if I go back over to the browser, I'll set isready to true so that the migration is allowed to continue. And then we'll call the reload function of reload.

Now, we can get access to that data that was saved by calling the migration data function, and, as a first parameter, passing the name of the migration that we used earlier. So we called it app. And you can see I get back an object with the key of name and a value of Chris. So what you'll see that packages do is when the JavaScript code first loads, we can call the _migrationdata function and pass in a key. And then we can do something with that data. For example, Session will initialize itself with the data that was stored away.

So where does the reload package put this data? It puts it into local storage. And so, your browser will need to support local storage in order for _migrationdata to work with the reload package. So this is a bit of a convoluted API, and we can wrap it with our own methods to make it a little bit easier to use.

But to recap what we've learned, we can call the _onmigrate method of reload, and that allows us to register a callback function that will get called before the browser reloads. As a parameter to that function, we get a retry function. And if we want to wait and do the migration at a later time, we can store away that retry function and call it later. When we call a later, what will happen is all of the _onmigrate callbacks will get called again, giving them a chance, once again, to return true or false. True if they're ready to migrate and false if they're not.

When we do the migration. If we return an array with true as the first value, we can pass an object as the second value. And that'll get stored away in local storage. And we can retrieve it again after the reload by calling reload._migrationdata and passing the name of our migration as a parameter.