0

I have a javascript file named js/jsClasses.js which is relative to to the index.html file.

This file has some nested functions. Here's the code -

function JSClass(){ //notice the capital J which though doesn't change execution is a convention indicating a class constructor
var langSetting;
this.setLanguage = function(){
    langSetting = "en-GB";
    console.log(langSetting);
}
this.getLanguage = function(){
    return langSetting;
}

}

I need to set the value of the variable langSetting in index.html. This will be the global variable and in all the subsequent pages, I need to access the value of langSetting and load the page in the corresponding language.

At the moment, this is how I am trying to access the js/jsClasses.js file from index.html

<html>
    <script src="js/jsClass.js">
        var object1 = new JSClass();
        object1.setLanguage();
        object1.getLanguage();
    </script>



</html>

When I click the button, nothing happens. Can someone please help ?

Ashish Agarwal
  • 14,555
  • 31
  • 86
  • 125

1 Answers1

2

There are two ways to solve this, a bad and common one and a good one,

The bad one is to remove the var key word from langSetting which would make it langSetting a global varaible.

The good one is to have JSClass return langSetting or more broadly an object revealing what it, as a module is willing to reveal, this is called the revealing module pattern, here is an excellent book chapter on it by Google developer Addy Osmani

Here is a good solution in your case:

var jsClass= function(){


    var langSetting = "en"; // this is javascript's version of a private variable, it is 'closed' in your jsClass

    var getLanguage = function(){
        return langSetting;
    }

    var setLanguage = function(){
        navigator.globalization.getPreferredLanguage(function (language){
            langSetting = language.value; //set the local variable
            console.log(langSetting);
        }, function(){
            console.log("there was an error");
        });
    }
    return {
        getLanguage:getLanguage,
        setLanguage:setLanguage
    };
}

Then in your code you can do

var obj = new jsClass(); // is exactly the same as var obj = jsClass , when functions return objects it doesn't matter if you use the 'new' keyword
obj.getLanguage(); //returns en

Another solution would be to use the constructor pattern. Some consider the constructor pattern as a mistake made to implement java developers migrating to javascript although it is widely used in the industry and in a lot of libraries. This would look the following way:

function JSClass(){ //notice the capital J which though doesn't change execution is a convention indicating a class constructor
    var langSetting;
    this.setLanguage = function(){
        //setter code here
    }
    this.getLanguage = function(){
        //getter code here
    }
}

and then use the new keyword, it would look like:

var myClass = new JSClass();
myClass.getLanguage();//getter result

Also, note I'm noticing that you're using Apache Cordova API for globalization, please note that makes setLanguage asynchronous, so you might want to have it accept a callback parameter which means you get to 'hook' on when it completes. See This stackoverflow question for more details on callbacks and how to use them.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • @AshishAgarwal please avoid making comments like 'it's not working' to answers as it will not help either of us, if you do not find my answer satisfactory or do not understand it I will gladly improve it but I have to know _what_ is not working for you, otherwise I won't be able to address your specific problem. Also, please avoid putting your script including the external source and the data inside the script in the same tag, see http://stackoverflow.com/questions/6528325/what-does-a-script-tag-with-src-and-content-mean – Benjamin Gruenbaum Feb 06 '13 at 22:59
  • I understand that. I am using the approach involving constructors (since I'm good at Java) but I am seeing nothing in the console logs. – Ashish Agarwal Feb 06 '13 at 23:14
  • It works if I place the entire source code in one file. But if I place the function JSClass() in another file (I am using js/jsClass.js), it does nothing i.e. I don't think it is even being called. – Ashish Agarwal Feb 06 '13 at 23:28
  • seperate the script calls to : (like the link I suggested) and see if it helps, I have tested it locally and it works but I don't know how to simulate this in jsfiddle – Benjamin Gruenbaum Feb 06 '13 at 23:29
  • Hmm, I am able to display an alert message. But I am not able to display the value on the console for some reason. I have var x = obj.getLanguage(); alert(x); console.log(x); That shows the alert as expected, but does not output to the console. Any idea why that might be happening ? – Ashish Agarwal Feb 06 '13 at 23:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24078/discussion-between-benjamin-gruenbaum-and-ashish-agarwal) – Benjamin Gruenbaum Feb 06 '13 at 23:37