execution order - new object's function undefined - javascript

I've created an app object which contains an empty modules object within it defined in the constructor.
var App = function() {
this.modules = {};
};
The modules object contains references to other objects (modules) that make up the app and contain their logic.
I instantiate the app like this
window.app = new App();
app.createModules();
createModules() fills the modules object with the modules of the app. Then when it is done, it runs initModules() that calls each modules init() function. In this way I hope to be able to control the execution order so that objects dependent on other objects will load correctly. The code for this is as follows:
App.prototype.createModules = function() {
console.log("Creating Modules");
this.modules = {
radio: new Radio(),
visualiser: new Visualiser()
};
this.initModules(this.modules);
}
App.prototype.initModules = function() {
console.log("Initialising modules");
for (var key in this.modules) {
if (this.modules.hasOwnProperty(key)) {
var obj = this.modules[key];
console.log(obj);
console.log(obj.init); //logs 'undefined'
}
}
}
Currently the console log on obj.init is returning undefined, meaning that I can't run the init code for that object. But when the page is finished loading if I call
app.modules.radio.init
It returns the function. I can't seem to figure out why is this happening.
Cheers!
EDIT
Here is the structure of app:
var app = function() {
...
}
window.app = new App();
app.createModules();
function Radio() {
...
}
Radio.prototype.init = function() {
...
}
function Visualiser() {
...
}
Visualiser.prototype.init = function() {
...
}
//Event code
Codepen: https://codepen.io/anon/pen/EvggLZ?editors=0011

Here is the structure of app
Yes, that calls the methods before they are created on the prototypes. Move the
window.app = new App();
app.createModules();
to the bottom of the script and it will work.

Related

How to export and import two different function objects in JavaScript?

I use Jasmine-Node to test Javascript code.
How can one export two different function objects like Confusions1 and Confusions2 so that both are available in the Jasmine-Node test file?
My attempt looks like this:
// confusions.js
var Confusions1 = function() {};
Confusions1.prototype.foo = function(num) {
// keep track of how many times `foo` is called
this.count++;
}
module.exports = Confusions1;
// second function object
var Confusions2 = function() {};
Confusions2.prototype.foo = function() {
var a = 2;
this.bar();
};
Confusions2.prototype.bar = function() {
return this.a;
}
module.exports = Confusions2;
And my Jasmine Test file:
// confusions.spec.js
var Confusion = require('./confusions.js');
describe("chapter 1, common misconception ", function() {
describe("to assume `this` refers to the function itself: ", function() {
var confusion = new Confusion();
// some test code omitted
});
describe("to assume `this` refers to the function's scope", function() {
var confusion = new Confusion();
// test code omitted
});
});
I want it so that Confusions1 and Confusions2 from confusions.js are both usable in the two nested describe blocks within confusions.spec.js
I assume that I have to somehow initialize different objects after requiring the file var Confusion = require('./confusions.js');
Something like var confusion1 = new Confusions1(); var confusion2 = new Confusions2(); But how exactly (without splitting both Objects in two separate files)?
So you want to have a module that behaves like a container of exported values, in another words you want to export two functions:
// foo.js
var Confusion1 = function() {}
var Confusion2 = function() {}
...
exports.Confusion1 = Confusion1
exports.Confusion2 = Confusion2
Wherever you need this module, you could require this stuff like:
// bar.test.js
var confusions = require('path-to-the-foo-file')
console.log(confusions.Confusion1)
console.log(confusions.Confusion2)
Also as it seems you should check how module system that you are using works in general, check this answer: module.exports vs exports in Node.js

JavaScript function prototype calling parent from child

I have a stupid reference problem
I declared a namespace variable called MYAPP
var MYAPP = MYAPP || function() {
this.name = 'My Application';
this.someImportantID = 123;
};
And then I wanted to sperate my code in namespaces/functions and so I did
MYAPP.prototype.homepage = function() {
urls: {
linkOne: '/link/to/some/page/',
linkTwo: '/link/to/some/page/'
},
doSomething: function() {
// ajax call
$getting = $.get(this.urls.linkOne)
// and so on .....
// how can I acces someImportantID ??
}
}
then i use it like this
app = new MYAPP();
app.homepage.doSomething();
but how can I access someImportantID within the function doSomething()
Get rid of this .homepage stuff. Why are you doing that anyway?
This is something of a constructor pattern. Declare your constructor:
var MYAPP = function(URLCollection) {
this._name = 'My Application';
this._someImportantID = 123;
this._URLCollection = URLCollection;
}
Then declare the instance methods:
MYAPP.prototype = {
doSomething: function() {
// ajax call
$getting = $.get(this._URLCollection.linkOne);
// and so on .....
// how can I acces someImportantID ??
}
}
Then declare your instance passing in your collection of links:
var lCollection = { linkOne: 'URL', linkTwo: 'URL' };
var myHomePage = new MYAPP(lCollection);
You can access doSomething from the instance:
myHomePage.doSomething();
You can get to some important ID from the instance also:
myHomePage._someImportantId;
Or from within the instance, by:
this._someImportantId;
This is rough - it should point you in the right direction.
If there are multiple MyApp instances then you can do the following:
//IIFE creating it's own scope, HomePage constructor
// is no longer globally available
;(function(){
var HomePage = function(urls,app){
this.urls=urls;
this.app=app;
}
HomePage.prototype.doSomething=function(){
console.log('urls:',this.urls,'app:',this.app);
}
//assuming window is the global
window.MyApp = function(urls){
this.name='app name';
this.homePage=new HomePage(urls,this);
}
}());
var app = new MyApp(['url one','url two']);
app.homePage.doSomething();
If you only have one app and that app only has one homePage object you can do it the following way as well:
var app = {
name:'app name'
,homePage:{
urls:['url one','url two']
,doSomething:function(){
console.log('urls:',this.urls,'app:',app);
//or
console.log('urls:',app.homePage.urls,'app:',app);
}
}
}
app.homePage.doSomething();
More on constructor functions, prototype and the value of this here.

How to communicate between javascript modules...?

In my application are a couple of modules for their own responsibility, and that's where I have some confusion..
How to communicate between modules?
How to inform or listen modules between to take decision for appropriate scenario..?
example:
module 1,
var MyModule1 = (function() {
var myPrivateData = 303;
function myPrivateFunction() {
alert('private');
}
return {
myPublicData : 42,
myPublicFunction : function() {
alert('public');
}
};
})();
Module 2
var MyModule2 = (function() {
var myPrivateName = privatized;
function myPrivateFunction() {
alert(myPrivateName) ;
}
return {
myPublicData : 42,
myPublicFunction : function() {
alert('public');
}
};
})();
How can I make them both communicate and listen to each other..? Can anyone please clarify with some small example? I need to share the privateData shared to module2 and myPrivate name shared with module1 and in case of any click event to be triggered.
Thanks in advance!
Here is basic concept of loosely coupled modules organization inside the browser:
When code inside module1 needs to notify others about some event it will do this:
$(document).trigger( "some:event", someData);
And module2 if it needs to be notified about "some:event" shall do this in its code on its initialization:
$(document).on( "some:event", function(evt,someData) {
// ... do something with the data ...
} );
In this schema two modules are completely independent. The only thing they shall to know are names of events they are communicating with.
Something like this
var ParentClass = (function() {
var privateVariable = 'toto';
this.publicVariable = 'titi';
this.ChildClass = new ChildClass(this);
this.ChildClass.execute();
});
function ChildClass(parent) { this.parent = parent; return this; };
ChildClass.prototype.execute = function() {
alert (this.parent.publicVariable); // show titi
};
ParentClass();

Storing different objects in same variable

I'm trying to figure out how i could store different objects in a certain "namespace".
I have something like this:
app.js
// This is the startup script:
var MyApp = {}
MyApp.ui = {}
MyApp.ui = require('ui/MainWindow');
MyApp.ui = require('ui/SecondWindow');
// Doesn't exist anymore because the 2nd require overwrites the
// first include
MyApp.ui.MainWindow.test;
Then i also have MainWindow.js and SecondWindow.js, which looks like this:
var MainWindow = {
test: "Main"
}
exports.MainWindow = MainWindow;
var SecondWindow = {
test: "Second"
}
exports.SecondWindow = SecondWindow;
The exports.XXXWindow = XXXWindow basically makes that object available.
So in my app.js i try to store the MainWindow object in MyApp.ui. So i can call it like this:
MyApp.ui.MainWindow.test
Then i'd also like to add the SecondWindow object to that. So i can call that in the same way:
MyApp.ui.SecondWindow.test
But the way i have it now causes the second require to overwrite the first one. So it now only points to SecondWindow. What do i have to do so that i can call both objects from MyApp.ui ??
I suggest you to do (I'm sorry if code is not syntactically correct but I use coffeescript and I'm not used anymore to Javascript):
MainWindow.js
var MainWindow = function() {
return {test: 'Main'};
};
module.exports = MainWindow;
SecondWindow.js
var SecondWindow = function() {
return {test: 'Second'};
};
module.exports = SecondWindow;
app.js
var myApp = {
ui: {
MainWindow: require('MainWindow.js'),
SecondWindow: require(SecondWindow.js)
}
};
Now my personal opinion. I prefer to do:
app.js
var MainWindow = require('MainWindow'),
SecondWindow = require('SecondWindow'),
myApp = {
ui: {
MainWindow: new MainWindow(),
SecondWindow: new SecondWindow()
}
};
The second assignment of MyApp.ui will overwrite its old value. However, you could do the following:
function inject(obj_into,obj_from){
for(var x in obj_from)
obj_into[x] = obj_from[x];
}
MyApp.ui = {MainWindow:{},SecondWindow:{}};
inject(MyApp.ui.MainWindow,require('ui/MainWindow'));
inject(MyApp.ui.SecondWindow,require('ui/SecondWindow'));
You first initialize MyApp.ui with empty property objects MainWindow,SecondWindow and fill them with inject.

JS turning a function into an object without using "return" in the function expression

i have seen in a framework (came across it once, and never again) where the developer defines a module like this:
core.module.define('module_name',function(){
//module tasks up here
this.init = function(){
//stuff done when module is initialized
}
});
since i never saw the framework again, i tried to build my own version of it and copying most of it's aspects - especially how the code looked like. i tried to do it, but i can't seem to call the module's init() because the callback is still a function and not an object. that's why i added return this
//my version
mycore.module.define('module_name',function(){
//module tasks up here
this.init = function(){
//stuff done when module is initialized
}
//i don't remember seeing this:
return this;
});
in mycore, i call the module this way (with the return this in the module definition):
var moduleDefinition = modules[moduleName].definition; //the callback
var module = moduleDefinition();
module.init();
how do i turn the callback function into an object but preserve the way it is defined (without the return this in the definition of the callback)?
you have to use:
var module = new moduleDefinition();
and then you're going to get an object.
Oh, and maybe you want to declare init as this:
this.init = function() {
Cheers.
How about something like this (I can only assume what mycore looks like):
mycore = {
module: {
definitions: {},
define: function(name, Module) {
this.definitions[name] = new Module();
this.definitions[name].init();
}
}
};
mycore.module.define('module_name', function () {
// module tasks up here
this.init = function () {
// init tasks here
console.log('init has been called');
};
});
I don't know what framework you're using or what requirements it places on you, but Javascript alone doesn't require a function to return anything, even a function that defines an object. For example:
function car(color) {
this.myColor = color;
this.getColor = function() {
return this.myColor;
}
//note: no return from this function
}
var redCar = new car('red');
var blueCar = new car('blue');
alert(redCar.getColor()); //alerts "red"
alert(blueCar.getColor()); //alerts "blue"
One more alternative http://jsfiddle.net/pWryb/
function module(core){this.core = core;}
function Core(){
this.module = new module(this);
}
Core.prototype.modules = {};
module.prototype.define = function(name, func){
this.core.modules[name] = new func();
this.core.modules[name].name = name;
this.core.modules[name].init();
// or
return this.core.modules[name];
}
var myCore = new Core();
var myModule = myCore.module.define('messageMaker', function(){
this.init = function(){
console.log("initializing " + this.name);
}
})
myModule.init();

Categories

Resources