0

I have many modules that are getting loaded depending on the request. I need a global variable that is limited to that connection, not the global scope of the entire code base.

Here is some sample code from Main Module.

var MainModule = function() {
   // Do something fun

}
MainModule.prototype.Request = function() {
  // Do more fun things
  var Mod = require('./MyModule');
  var MyModule = new Mod(this);
}
module.exports = MainModule;

.

var MyModule = function(MainModule) {
  // Make MainModule Global ??
  this.MainModule = MainModule;
}

MyModule.prototype.Foo = function() {

  AnotherFunction('321312',function() {
    // Need MainModule in this callback
  }
}
module.exports = MyModule;

I want this from MainModule to be global in MyModule as another name of course. The only way I have found to handle this is to create this.MyModule but that gets cumbersome on each module and more cumbersome when there are many sub modules.

Is there a clean way to handle getting a variable that can be Global in the scope for a module?

  • There is no global environment "per connection", and therefore there are no global variables for it. If you are constructing one instance per request of that module, then a property of that instance is the best you'll get. – Bergi Jul 22 '15 at 19:14
  • Unfortunately I am still having problems passing that instance downward through callbacks. – Adrian Stride Jul 22 '15 at 19:23
  • See [How to access the correct `this` / context inside a callback?](http://stackoverflow.com/q/20279484/1048572) for that. Alternatively just don't define your methods on the prototype but rather inside the constructor, and directly access the `MainModule` variable that your paramter declares. – Bergi Jul 22 '15 at 19:27

3 Answers3

0

Is that what you are trying to do ?

MyModule.prototype.Foo = function() {
  var that = this;
  AnotherFunction('321312',function() {
    that.MainModule;
  }
}
DarkChipolata
  • 925
  • 1
  • 10
  • 29
  • Yes, however with out redefining the variable when there are thousands of functions and callbacks. When using that method, even with proper namespacing I seem to be losing the copy of that object. Somewhere it seems to be copying and not point to the original object. – Adrian Stride Jul 22 '15 at 19:22
  • I don't really understand why it doesn't fits your needs. It's the traditional way to deal with that kind of problem in JS, and it should not copy `this`, as applying the `=` operator on an object makes a reference assignment. Something must be wrong in my comprehension of the problem. Are we agree on the fact that you want to access `this` from a sub-function of a function ? What I call a sub-function is a function definition inside another one : `function() { function() {} }` – DarkChipolata Jul 23 '15 at 17:04
  • The `that` example doesn't work when you have multiple levels of functions calling modules. It changes the reference as you go down through callback hell. – Adrian Stride Jul 23 '15 at 17:08
  • It shouldn't ... You used `that` instead of `this` in the callbacks ? – DarkChipolata Jul 23 '15 at 17:22
  • Yes, but when you have a callback loading a module with another callback, `that` gets lost. – Adrian Stride Jul 24 '15 at 18:55
  • The thing that I don't understand is that `var MainModule = this.MainModule` works, but `var that = this` doesn't. In the two cases, `MainModule` and `that` are accessible from the callback function as the scope of the callback is a part of the scope of `MyModule.prototype.Foo`. Can the original code be seen ? You have simplified the situation in order to explain us your problem, but something else must make the second solution (the most common one) not working. – DarkChipolata Jul 26 '15 at 19:45
0

If I understood correctly then you could use the fact that a module is only loaded once and then cached, to create a var that will be around for the lifetime of the app but is private to the module. It can be define at the top level scope of the module, outside of exports. You still need to set it once at before you use it in Foo though.

// modules are cached so its like a global to the module
var internalModuleGlobal;

var MyModule = function() {

}

MyModule.prototype.Foo = function() {

  AnotherFunction('321312',function() {
    if(!internalModuleGlobal) throw new Error("set internalModuleGlobal first!"); 
    // Need MainModule in this callback
    internalModuleGlobal.whatever; // accessible via closure
  }
}

// call this once before Foo. doesn't have to be part of MyModule but is for e.
MyModule.prototype.setModuleOnce(mainModule) {
   internalModuleGlobal = mainModule;
}
module.exports = MyModule;
longplay
  • 206
  • 3
  • 7
  • That is what I am looking for but I need to test to see if it is per instance or per module. For example, each request will obviously share the module instance, but not the object instance. I need it unique the the object not the module because multiple requests should not see the same object. – Adrian Stride Jul 22 '15 at 20:16
0

The only way I have been able to solve this is to pass the reference into each module.

var MyModule = function(MainModule) {
  // Set it to pass it so all the methods
  this.MainModule = MainModule;
}

MyModule.prototype.Foo = function() {
  // Set it again to pass it through to any callbacks or sub functions
  var MainModule = this.MainModule;
  AnotherFunction('321312',function() {
    MainModule.SomeMethod(); 
  }
}
module.exports = MyModule;

So every Module I load throughout the code that needs to know the request or user information has to have the variable referenced through it.

I need to do some testing to make sure it is properly referencing it all the way and never copying it into an new object.