Search code examples
javascriptrequirejsjs-amdmodule-pattern

RequireJS setting Module variables from outside doesnt take effect


Im having trouble setting variables within a requireJS Define module, it flatout doesnt take effect. I have the following (cutdown) example to illustrate the issue:

Here is the defined module:

define([], function () {
var testerString = "BaseLine";

var ShowTesterString = function () {
    console.log(testerString);
}

var setTesterString = function (pTesterString) {
    testerString = pTesterString;
}

return {
    testerString: testerString,
    ShowTesterString: ShowTesterString,
    setTesterString: setTesterString
};  
});

I than set the "TesterModule" as a dependency of another and run the following lines of code:

TesterModule.ShowTesterString();
TesterModule.testerString = "Change 1";
TesterModule.ShowTesterString();
TesterModule.setTesterString("Change in Setter");
TesterModule.ShowTesterString();

What gets outputted to the console is:

BaseLine 
BaseLine 
Change in Setter 

I would have thought that it should be :

BaseLine 
Change 1
Change in Setter 

It seems that setting a variable in a module just by doing variable = blah doesnt take any effect, it seems to require to set variables within a method of the module. Can anyone explain to me why this is? Or what I am coding wrong?

Thanks in advance


Solution

  • As far as I can tell, not being super-familiar with RequireJS, this is a pure-JavaScript problem. Change

    console.log(testerString);
    // to
    console.log(this.testerString);
    

    and change

    testerString = pTesterString;
    // to
    this.testerString = pTesterString;
    

    so that you're getting/setting the value in the object returned by the anonymous function, rather than closing over the var testerString variable. What's happening in your code currently may be clarified if you use variable names that differ from the returned object keys:

    define([], function () {
        var foo = "BaseLine";
    
        var ShowTesterString = function () {
            console.log(foo);
        }
    
        var setTesterString = function (pTesterString) {
            foo = pTesterString;
        }
    
        return {
            testerString: foo,
            ShowTesterString: ShowTesterString,
            setTesterString: setTesterString
        };  
    });
    

    Also, as a matter of style, it's better to use a "normal" function declaration:

    function ShowTesterString () {
        ...
    }
    

    than to use var ShowTesterString = function () { ... }, as in your code.