Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with dynamic loading in JavaScript

Tags:

javascript

I am a JavaScript newbie and learn by working on a pure JavaScript "project" that calculates mathematical functions. It all works well. Now, as a further step, I want to make the messaging multilingual. The code should be capable of loading the appropriate language file at runtime. For the dynamic loading issue, I read and found solutions on Web pages like this one.

Before writing the dynamic code, I loaded it statically and the test code worked well. The code I am asking for help about is just making the minor difference of loading a "script" element.

The code where I run into problems is the this.getString function, where it is not possible to access the de element in the language file. At line console.log(eval(language, tag));, I get the error message "Uncaught ReferenceError: de is not defined".

//File: Utils/Lang/js/FileUtils.js
function Language(language) {
    var __construct = function(dynamicLoad) {
        if (typeof language == 'undefined') {
            language = "en";
        }
        // Load the proper language file:
        loadFile("js/resources/lang.de.js");
        return;
    } ()

    this.getString = function(tag, strDefault) {
        console.log("getString(" + tag + ", " + strDefault + "): ");
        console.log("getString(...): document = " + document);
        console.log("getString(...): eval(" + language + ", " + tag + ") = ");
        console.log(eval(language, tag));
        var strReturn = eval('eval(language).' + tag);

        if (typeof strReturn != 'undefined') {
            return strReturn;
        } else {
            return (typeof strDefault != 'undefined') 
                ? strDefault
                    : eval('en.' + tag);
        }
    }
}

The static test code that works is not included, where I can access the de element.

My question: How to load the language file properly so that the de tag is accessible?

Thank you for your help!

 //File: Utils/Files/js/FileUtils.js
 function loadFile(filepathname) {
     var reference = document.createElement('script');

     reference.setAttribute("type", "text/javascript");
     reference.setAttribute("src", filepathname);

     if (typeof reference != 'undefined') {
       document.getElementsByTagName("head")[0].appendChild(reference);
     }
     console.log("loadFile(\"" + filepathname + "\"): document = " + document);
   }
 //File: Utils/Lang/js/resources/lang.de.js:
 de = {
   pleaseWait: "Bitte warten..."
 };

 //File: Utils/Lang/js/resources/lang.en.js
 en = {
   pleaseWait: "Please wait..."
 };

 //File: Utils/Lang/js/TestLanguage.js:
 function output() {
   console.log("output()");
   var codes = ['de', 'en'];

   for (var i = 0; i < codes.length; i++) {
     var translator = new Language(codes[i]);

     var message = "output(): in " + translator.getLanguage() + ": ";

     message += translator.getString('pleaseWait');

     console.log(message);
   }
 }
<!--File: Utils/Lang/TestLang.html:-->
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
  <title>Test languages</title>
  <script type="text/javascript" src="../Files/js/FileUtils.js"></script>

  <script type="text/javascript" src="js/Language.js"></script>
  <script type="text/javascript" src="js/TestLanguage.js"></script>
</head>

<body>
  <button name="outputButton" onclick="output();">Click</button>
  <br>Please press [F12] so that you can see the test results.
</body>

</html>
like image 552
Sae1962 Avatar asked Oct 19 '22 13:10

Sae1962


1 Answers

When you add the script tag to your document, it is not loaded synchronously. You need to wait for the file to be loaded before you can use the code that was in it.

you may be able to redesign your code to use a script.onload callback:

var reference = document.createElement('script');
// ...
reference.onload = function() {
  alert("Script loaded and ready");
};

but for this scenario, if you don't have many language string you may be best to just load them all statically.

like image 82
GarethOwen Avatar answered Oct 22 '22 02:10

GarethOwen