I'm trying to hotwire webpack to use some legacy code but this arrangement:
slidesystem.js:
export var slideSystem = (function () {
var position = 0;
function init() {
alert('winner!');
} // init
})();
app.js
import {slideSystem} from './slidesystem';
slideSystem.init();
alert(slideSystem.position);
Isn't working as expected... Is there a better way to do this?
Here's one way to do it using the demo above:
slidesystem.js
const slideSystem = (function () {
'use strict';
var position = 0;
function init() {
alert('winner!');
} // init
return {
init: init,
pos: pos
};
})();
export default slideSystem;
app.js
import {slideSystem} from './slidesystem';
slideSystem.init();
alert(slideSystem.position);
Related
I have an existing code with multiple JS files. Each file adds new property with object literal onto global namespace. It seems bunch of Java developers worked on this project looking at the pattern where you would end up with a method foo in App.product.foo()
Current (as is) code:
// product.js
var app = app || {};
app.product = {
changeColor = function(e) {};
clickEventHandler = function() {
app.cart.addToCart(e.target.dataset['code']);
};
}
// cart.js
var app = app || {};
app.cart = {
addToCart = function(productCode) {}
}
Can I convert this into ES6 modules pattern so that I can export / import required code across modules?
// product.js
import { addToCart } from './cart';
export default {
changeColor = function(e) {};
clickEventHandler = function() {
addToCart(e.target.dataset['code']);
};
}
I have an angular app that will not load and is returning the error message:
Error: [$injector:unpr] Unknown provider: navigatorProvider <-
navigator <- LayoutController
This is ever since I introduced a service I have this registered on the controller, but it still not working. The controller referenced is:
(function () {
"use strict";
angular.module("HtJobPortal").controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "navigator"];
function LayoutController($scope, navigator){
var layout = this;
// Layout
layout.loadTemplate = function() {
return navigator.loadTemplate();
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
}
})();
This is the service:
(function() {
var navigator = angular.module('navigator', []);
navigator.factory('loadTemplate', function () {
var loadTemplate = this;
// Page Directory
navigator.login = "templates/login.html";
navigator.dashboard = "templates/dashboard.html";
navigator.job = "templates/job.html";
// Template switcher
navigator.loadTemplate = function () {
return navigator.login;
}
return loadTemplate;
});
}());
And the app page just in case I've missed something there:
(function () {
'use strict';
angular.module('HtJobPortal', []);
})();
You are add the dependencies when defining the HtJobPortal module
//define dependencies
angular.module('HtJobPortal', ['navigator']);
In the controller, you need to inject the factory in controller
(function () {
"use strict";
angular.module("HtJobPortal").controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "loadTemplate"];
function LayoutController($scope, loadTemplate){
var layout = this;
// Layout
layout.loadTemplate = function() {
return loadTemplate.loadTemplate();
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
}
})();
And define factory as
(function () {
angular.module('navigator', []).factory('loadTemplate', function () {
// Page Directory
var login = "templates/login.html";
var dashboard = "templates/dashboard.html";
var job = "templates/job.html";
return {
// Template switcher
loadTemplate: function () {
return login;
}
};
});
})();
To create a factory\service\controllers , you generally don't require a new module every time. It's preferred to declare one module and register your controller\factory\services to same.
In your case, you can do it like:
(function() {
angular.module('HtJobPortal', [..define other module dependency here..]);
angular.module('HtJobPortal')
.factory('loadTemplate', function () {
var loadTemplate = {};
// Page Directory
loadTemplate.login = "templates/login.html";
loadTemplate.dashboard = "templates/dashboard.html";
loadTemplate.job = "templates/job.html";
// Template switcher
loadTemplate.loadTemplate = function () {
return loadTemplate .login;
}
return loadTemplate; // return object from factory
})
.controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "loadTemplate"]; //inject factory
function LayoutController($scope, loadTemplate){
var layout = this;
// Layout
layout.loadTemplate = function() {
return loadTemplate.loadTemplate(); // call factory method
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
};
}());
Question:
A seemingly simple question that I've been researching on and off the for past 2 weeks (please go easy as I'm new to all this!):
How does one neatly implement inheritance in JavaScript when using Require.js and the Revealing Module Pattern?
Example:
Here is an example module which is the base class of some type of 'Component':
define('Component', [], function () {
"use strict";
var _privateVar = 10;
var _doPrivateThings = function () { /* do stuff */ };
var init = function () { /* do stuff */ };
var update = function () { /* do stuff */ };
return {
init : init,
update : update
};
});
Next I want to implement CakeComponent which should inherit everything from Component and allow me to edit/add methods and properties:
define('CakeComponent', ['Component'], function (Component) {
"use strict";
// Setup inheritance
var CakeComponent = function() {}
CakeComponent.prototype = new Component();
// Add/edit methods/properties
CakeComponent.prototype.newMethod = function () { /* do stuff */ };
return {
init : CakeComponent.init,
update : CakeComponent.update,
newMethod : CakeComponent.newMethod
};
});
Firstly, I'm not sure if that makes complete sense, but secondly, my CakeComponent feels a bit gross because now I've got this CakeComponent redundancy everywhere and I've had to 're-reveal' the init and update methods.
I would really prefer something like this (I realise this doesn't make sense, it's really just pseudo-code):
define('CakeComponent', ['Component'], function (Component) {
"use strict";
this.extends(Component);
var newMethod = function () { /* do stuff */ };
return {
newMethod : newMethod
};
});
Any tips or suggestions would really be appreciated. Thanks.
Further Details
Maybe I should always be creating a class object within the define wrapper? I've seen people do this but it seemed unnecessary until I came across this problem.
Would the .call() method on the function object be useful at all in this context? e.g. using Component.call()
#Bergi please see below:
define([], function () {
"use strict";
var Component = function () {
var _privateVar = 10;
var _doPrivateThings = function () { /* do stuff */ };
this.init = function () { /* do stuff */ };
this.update = function () { /* do stuff */ };
};
return Component;
});
I have seen this model used before, called Universal Module Definition:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['Component'], factory);
} else {
root.CakeComponent = factory(root.Component);
}
}(this, function (Component) {
return {
newMethod: function(){ /* do stuff */ }
};
}));
You could try this, which is not "real" inheritance - in case it does not work - depending on environment, you might need to pass the base functions as well, which is a pity:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['Component'], factory);
} else {
root.CakeComponent = factory(root.Component);
}
}(this, function (Component) {
return {
init: Component.init,
update: Component.update,
newMethod: function(){ /* do stuff */ }
};
}));
You can read more to this Topic in this fantastic article about the Universal Module Definition
Currently, I write node.js modules like this:
//MyModule.js
function MyModule() {
...somecode
}
MyModule.prototype.someFunc = function() {...}
module.exports = MyModule
However, when I need to use the module, I have to write something like this:
//main.js
var MyModule = require('MyModule');
var myModule = new MyModule();
This seems terribly ugly. Isn't there some way to do something like this
//main.js
var myModule = require('MyModule').new();
Am I doing something wrong?
quick hack for something not ugly
module.js
function MyModule() {
console.dir('constructor');
}
module.exports = MyModule;
app.js
Function.prototype.new = function () {
return new this();
};
var MyModule = require('./module.js').new(); // 'constructor'
If your module consists solely of functions, it may not need to be created as an instance - just define your module as being an object filled with functions. Like so:
var MyModule = {
prepareHtmlContent: function() {
},
autoLoadActionInitiatorFunctions: function() {
}
};
The reason I suggest this is that you've referred to your object as 'MyModule'. If your intent is specifically to use it as a 'Class', and instantiate separate copies of it when they're needed, then you're doing it the correct way.
Here is what I use
(function(module) {
module.myFunction = function() {
}
module.createSomeObj = function() {
return {
foo: 1,
bar: 'bar'
};
}
}(module.exports));
Usage
var myModule = require('./myModule');
myModule.myFunction();
var myObject = myModule.createSomeObj();
Consider the following Typescript code:
module demoAppModule{
'use strict';
export module nest{
export var hello = function () {
alert('Hello!');
};
}
}
demoAppModule.nest.hello();
After transpiling we have the following javascript code:
var demoAppModule;
(function (demoAppModule) {
'use strict';
(function (nest) {
nest.hello = function () {
alert('Hello!');
};
})(demoAppModule.nest || (demoAppModule.nest = {}));
var nest = demoAppModule.nest;
})(demoAppModule || (demoAppModule = {}));
demoAppModule.nest.hello();
Why is this line generated? It hurts my eyes.
var nest = demoAppModule.nest;
Short Answer: Its needed to access the module variable locally. E.g.
module demoAppModule{
'use strict';
export module nest{
export var hello = function () {
alert('Hello!');
};
}
// The following would not be possible without that line
console.log(nest.hello);
}
demoAppModule.nest.hello();
Longer Answer: Its similar to the var added before a module e.g. notice var x:
// TypeScript
module x{export var foo;}
// Generated JavaScript
var x;
(function (x) {
x.foo;
})(x || (x = {}));
But when you are inside a module + export a module the var needs to be added to outermodule.innermodule so you do not do var innermodule upfront. You add it to outermodule and then create a local variable to point to the innermodule which you can see in the generated javascript:
// Notice var here
var demoAppModule;
(function (demoAppModule) {
'use strict';
// Notice no var here
(function (nest) {
nest.hello = function () {
alert('Hello!');
};
})(demoAppModule.nest || (demoAppModule.nest = {}));
// Notice var assinged afterwards
var nest = demoAppModule.nest;
// The following would not be possible without that line
console.log(nest.hello);
})(demoAppModule || (demoAppModule = {}));
demoAppModule.nest.hello();