Cascading object declaration gives undefined typeof from second object on

165 views Asked by At

I load js files dynamically in my project putting their content in a script tag in the head. Each file has only an object inside. I noticed that after loading, all objects are in the script tag but only the first is not undefined (the order I put content doesn't change the problem, first is an object, others nope)

This is the script

window.onload = function () {objMaster.end(objMaster.main());};    

objMaster = {


    // ---------- MAIN


    main: function () {
        // Setting up the environment
        if (!this.set()) return 101;
        // Loading core modules
        if (!this.load('FrameBee/Core/1_Engineer.js', 'js')) return 201;
        if (!this.load('FrameBee/Core/2_Manager.js', 'tmp_js')) return 202;
        if (!this.load('FrameBee/Core/3_Lumberjack.js', 'tmp_js')) return 203;
        if (!this.load('FrameBee/Core/4_Recruiter.js', 'tmp_js')) return 204;
        if (!this.load('FrameBee/Core/5_Sage.js', 'tmp_js')) return 205;
        if (!this.load('FrameBee/Core/6_Architect.js', 'tmp_js')) return 206;
        if (!this.load('FrameBee/Core/7_Agent.js', 'tmp_js')) return 207;
        // Checking core objects declaration
        if (typeof objManager !== 'object') return 301;
        if (typeof objLumberjack !== 'object') return 302;
        if (typeof objRecruiter !== 'object') return 303;
        if (typeof objSage !== 'object') return 304;
        if (typeof objArchitect !== 'object') return 305;
        if (typeof objAgent !== 'object') return 306;
        return 1;
    },


    // ---------- ENDING MAIN


    end: function (valIN) {
        var strOUT = null;
        // Setting up the error message if main() is not true
        switch (valIN) {
            // Environment
            case 101:
                strOUT = this.att.error.environment;
                break;
            // Loading core modules
            case 201:
                strOUT = 'Engineer' + this.att.error.unreachable;
                break;
            case 202:
                strOUT = 'Manager' + this.att.error.unreachable;
                break;
            case 203:
                strOUT = 'LumberJack' + this.att.error.unreachable;
                break;
            case 204:
                strOUT = 'Recruiter' + this.att.error.unreachable;
                break;
            case 205:
                strOUT = 'Sage' + this.att.error.unreachable;
                break;
            case 206:
                strOUT = 'Architect' + this.att.error.unreachable;
                break;
            case 207:
                strOUT = 'Agent' + this.att.error.unreachable;
                break;
            // Checking core objects
            case 301:
                strOUT = 'Manager' + this.att.error.undeclared;
                break;
            case 302:
                strOUT = 'Lumberjack' + this.att.error.undeclared;
                break;
            case 303:
                strOUT = 'Recruiter' + this.att.error.undeclared;
                break;
            case 304:
                strOUT = 'Sage' + this.att.error.undeclared;
                break;
            case 305:
                strOUT = 'Architect' + this.att.error.undeclared;
                break;
            case 306:
                strOUT = 'Agent' + this.att.error.undeclared;
                break;
        }
        // Showing error message only if main() is not true
        if (strOUT !== null) document.body.innerHTML =
            this.att.error.open +
            strOUT +
            this.att.error.close;
        return 1;
    },


    // ---------- ATTRIBUTES


    att: {
        // Class identifier for removing temporary elements in the end
        tmp_class: 'FrameBee_Temp',
        // IDs of FrameBee head tag environment
        id: {
            style: 'FrameBee_Head_Style',
            tmp_style: 'FrameBee_Head_Style_Temp',
            script: 'FrameBee_Head_Script',
            tmp_script: 'FrameBee_Head_Script_Temp',
        },
        // Error messages
        error: {
            // Enclousers
            open: '<h1>FrameBee ERROR</h1><p>:: ',
            close: '</p><hr><i>Application is halted</i>',
            // Suffix
            environment: 'Environment is not properly setted',
            unreachable: ' core module is not reachable',
            undeclared: ' object is not declared',
        },
    },


    // ---------- METHODS


    // .......... Set the HTML environment

    set: function () {
        var elmTMP = null;
        // Adding style element
        elmTMP = document.createElement('style');
        elmTMP.setAttribute('id', this.att.id.style);
        elmTMP.setAttribute('type', 'text/css');
        elmTMP.setAttribute('rel', 'stylesheet');
        document.head.appendChild(elmTMP);
        // Adding temp style element
        elmTMP = document.createElement('style');
        elmTMP.setAttribute('id', this.att.id.tmp_style);
        elmTMP.setAttribute('class', this.att.tmp_class);
        elmTMP.setAttribute('type', 'text/css');
        elmTMP.setAttribute('rel', 'stylesheet');
        document.head.appendChild(elmTMP);
        // Adding script element
        elmTMP = document.createElement('script');
        elmTMP.setAttribute('id', this.att.id.script);
        elmTMP.setAttribute('type', 'text/javascript');
        document.head.appendChild(elmTMP);
        // Adding temp script element
        elmTMP = document.createElement('script');
        elmTMP.setAttribute('id', this.att.id.tmp_script);
        elmTMP.setAttribute('class', this.att.tmp_class);
        elmTMP.setAttribute('type', 'text/javascript');
        document.head.appendChild(elmTMP);
        // Checking the environment
        if (
            document.getElementById(this.att.id.style) === null ||
            document.getElementById(this.att.id.tmp_style) === null ||
            document.getElementById(this.att.id.script) === null ||
            document.getElementById(this.att.id.tmp_script) === null
            ) return 0;
        if (
            document.getElementById(this.att.id.tmp_style).className.indexOf(this.att.tmp_class) < 0 ||
            document.getElementById(this.att.id.tmp_script).className.indexOf(this.att.tmp_class) < 0
            ) return 0;
        return 1;
    },

    // .......... [-] Get file content if file exists

    get: function (pthIN) {
        var reqTMP = new XMLHttpRequest();
        reqTMP.open('GET', pthIN, false);
        reqTMP.send(null);
        if (reqTMP.status !== 200) return 0;
        return reqTMP.response;
    },

    // .......... [-] Add content to head tags

    add: function (txtIN, catIN) {
        var attTMP = null;
        switch (catIN) {
            case 'css':
                attTMP = this.att.id.style;
                break;
            case 'tmp_css':
                attTMP = this.att.id.tmp_style;
                break;
            case 'js':
                attTMP = this.att.id.script;
                break;
            case 'tmp_js':
                attTMP = this.att.id.tmp_script;
                break;
        }
        if (attTMP === null) return 0;
        document.getElementById(attTMP).innerHTML += txtIN;
        return 1;
    },

    // .......... [+] Load core module

    load: function (pthIN, catIN) {
        var valTMP = this.get(pthIN);
        if (valTMP === 0) return 0;
        if (this.add(valTMP, catIN) === 0) return 0;
        return 1;
    },

    //// .......... Check if object is defined

    //check: function (objIN) {
    //    if (typeof objIN !== 'object') return 0;
    //    return 1;
    //},

};

All js files are same this two (changing the name)

/* 
    FrameBee Framework version 0.2
    THE MANAGER . Resources Manager
*/

objManager = {};

or this one

/* 
    FrameBee Framework version 0.2
    THE LUMBERJACK . Global logger
*/

objLumberjack = {};

here the script tag result

<script class="FrameBee_Temp" id="FrameBee_Head_Script_Temp" type="text/javascript">
/* 
    FrameBee Framework version 0.2
    THE MANAGER . Resources Manager
*/



objManager = {};
/* 
    FrameBee Framework version 0.2
    THE LUMBERJACK . Global logger
*/



objLumberjack = {};
/* 
    FrameBee Framework version 0.2
    THE RECRUITER . Resources Loader
*/



objRecruiter = {};
/* 
    FrameBee Framework version 0.2
    THE SAGE . Classes guard
*/



objSage = {};
/* 
    FrameBee Framework version 0.2
    THE ARCHITECT . Style definition
*/



objArchitect = {};
/* 
    FrameBee Framework version 0.2
    THE AGENT . Style applyer
*/



objAgent = {};
</script>

Here a live example of the code

2

There are 2 answers

4
Pavel Gatnar On

There is a big difference between loading and executing. The best place to check all objects are ready is on DOMContentLoaded event.

0
Giacomo On

I would use Javascript to load all core modules but I will change to JQuery. The problem is related to the xmlhttprequest method plus the innerHtml method. First time, the browser interpret the code inside. From second on it just add the content. To continue on this way it would be better to create an element (script) each time and append it to the head

var elm = document.createElement('script');
elm.innerHtml = //content retrieved;
document.head.appendChild(elm);