I'm writing an app that is using a revealing-ish module pattern. I'm using Gulp for compilation, so I can set the order of compilation. Aside from some jQuery, there aren't any other frameworks or libraries at play.
I'm trying to break the files up:
- The site's main JS file,
- one for a respective feature's general settings,
- one for the feature's UI,
- and another for the feature's data.
I'm trying to namespace as follows:
myApp
myApp.dashboard
myApp.dashboard.ui
myApp.dashboard.data
The problem is the namespace nesting because (for example) my dashboard.ui.js file is referenced in dashboard.js
I receive
Uncaught TypeError: Cannot set property 'ui' of undefined when it tries to access the myApp.dashboard.ui.
I've tried every order of compilation I can think of. I'm guessing there's something wrong with my pattern but I'm not sure what. Here's an example of the code.
// app.js
let myApp = (function(){
const $els = {
menu: $('#menu')
// etc.
};
const eventHandlers = () => {
//site-wide click event handlers (for example)
};
const utils = {
// utility functions
};
const init = () => {
// set some site variables, etc.
eventHandlers();
};
return {
init,
utils
};
})(myApp || {});
//dashboard.js
myApp.dashboard = (function (parent){
// ! need access to the UI
let ui = parent.dashboard.ui;
const eventHandlers = () => {
...
};
const init = () => {
eventHandlers();
};
return {
init
};
})(myApp || {});
//dashboard.ui.js
myApp.dashboard.ui = (function (parent){
// ! need access to the DATA
let ui = parent.dashboard.data;
const htmlTemplate = (content) => {
return `<h1>${content}</h1>`;
};
const setValidationFlags = () => {
...
};
return {
setValidationFlags
};
})(myApp || {});
//dashboard.data.js
myApp.dashboard.data = (function (parent){
const getData = (dataObject) => {
// do XHR look up
// call setter, etc.
};
const parseForm = () => {
// collect form data.
};
return {
parseForm
};
})(myApp || {});
Can someone please provide some guidance on how to correct my code so that I can nest the UI and Data portions under the myApp.dashboard namespace and have the three accessible to one another?
If this pattern is way off base, pointers on how to improve it are also welcome.
dashboardrequiresuirequiresdata, so you need to load them in the reverse order. And have each module set up the whole namespace tree it needs when it is not yet available:The alternative would be not to use references to the other modules inside the IIFE that is executed immediately, but to defer them until the
initcall which is when all modules should have been loaded.