After years working with Blaze, I was never able to figure out how to access a template instance inside a method call from the method stub. A quick refresher from the docs
If you do define a stub, when a client invokes a server method it will also run its stub in parallel. On the client, the return value of a stub is ignored. Stubs are run for their side-effects: they are intended to simulate the result of what the server’s method will do, but without waiting for the round trip delay. If a stub throws an exception it will be logged to the console.
and then I suddenly had this epiphany and thought I share it.
Here is a usual Template.onCreated
where I call a method getSecureString
, in the simulation I want to be able to pre-set the result while the server part of the method is doing it’s job. As an example I defined the method to take the parameter nameOfReactiveVar
to set to the simulated value. In the simulated portion of the method I can access the current template instance via Blaze.currentView.templateInstance()
and everything that is defined within that instance
Template.hello.onCreated(function helloOnCreated() {
var instance = this;
instance.secureString = new ReactiveVar('');
Meteor.call('getSecureString', 'secureString' , (error, secureString) => {
if (error) {
console.error(error.message);
} else {
instance.secureString.set(secureString);
}
});
});
Here is the definition of the method, it exists both on the client (isSimulation) as well as on the server, so when the client calls this method the simulation
runs
import { Random } from 'meteor/random';
Meteor.methods({
getSecureString(nameOfReactiveVar) {
if(this.isSimulation) {
//
// we are still on the client, find out what template instance called us
//
const instance = Blaze.currentView.templateInstance();
//
// check if the instance has a ReactiveVar nameOfReactiveVar
//
if(instance && instance[nameOfReactiveVar] != undefined && instance[nameOfReactiveVar] instanceof ReactiveVar) {
instance[nameOfReactiveVar].set(`calling server, please wait ... ${Random.id()}`);
}
} else {
//
// this is happening on the server
//
this.unblock();
let secureString = 'No user logged in. Please login in user and try again.';
// make the method delay for 5 seconds
Meteor._sleepForMs(5000);
if (this.userId != null) {
secureString = `This is from the server: ${Random.id()}`;
}
return secureString;
}
},
})