ES6: Save variable into module scope - javascript

I'd like to know if and how it's possible to save the following config into my modules scope (think of the block below as one module):
var config = null;
var mySingleton = {
init: function(config) {
config = config; // Naming conflict!
},
printConfig: function() {
console.log(config); // Undefined!
}
};
export { mySingleton };
Unfortunately, a naming conflict occurs. I'd need something like module.config = config;.
Note: I'm using the es6-module-transpiler.

No. It's a simple variable, and not a global one (where it would be accessible as a property of the global object), so it just is shadowed and not available "namespaced".
You need to use a different name to resolve conflicts, which should be trivial and will cause no effects outside the module:
var config = null;
var mySingleton = {
init: function(conf) {
config = conf;
},
printConfig: function() {
console.log(config);
}
};
export { mySingleton };

Related

Instantiating module object on module's file vs. instantiating module object on file that uses it

Are there any advantages/disadvantages to instantiate a module object on the module's file instead of instantiaing the module object on the file that uses it?
Example of Instantiating module on the module's file:
module.js
const someModule = (function() {
const doSomething = function(id) {
console.log("doing something");
};
return {
doSomething: doSomething
};
})();
export someModule;
main.js
import { someModule } from "./module";
someModule.doSomething();
Example of instantiating module on the file that uses it:
module.js
const someModule = function() {
const doSomething = function(id) {
console.log("doing something");
};
return {
doSomething: doSomething
};
};
export someModule;
main.js
import { someModule } from "./module";
someModuleInstance = new someModule();
someMosomeModuleInstance.doSomething();
The first example only has "someModule"(from the import statement) on the main file's global scope while the second example has both "someModule" and its instance on the global scope. So is the first example better?

Knockout: Change observable value

I use a requirejs/crossroads setup.
This is my bootstrapping with some global properties:
ko.applyBindings({
route: router.currentRoute,
user: {
...
},
...
loading: ko.observable(false),
setLoadingState: function(newState) {
this.loading(newState);
}
});
When calling the setLoadingState function from components (passed via params), it tells me that loading is not a function/undefined.
What's the correct way of implementing such mechanisms?
Note that in your (simplified?) example, you don't need an additional method since it only forwards to loading, which can be called directly.
Either use a class like pattern to make sure this refers to your view model like so:
var MyApp = function(router) {
this.route = router.currentRoute,
this.loading = ko.observable(false);
};
MyApp.prototype.setLoadingState = function(newState) {
this.loading(newState);
};
ko.applyBindings(new MyApp(router));
(you can also use the more modern class syntax)
or, use plain objects via a "factory" function:
var MyApp = function(router) {
var route = router.currentRoute,
var loading = ko.observable(false);
var setLoadingState = function(newState) {
loading(newState);
};
// Expose what you want to expose:
return {
loading: loading,
setLoadingState: setLoadingState
};
};
ko.applyBindings(MyApp(router));

Cannot access variables outside scope in browser context

Using protractor for angular e2e tests. I have a scope problem with the addMockModule. The spec states:
The JavaScript to load the module. Note that this will be executed in
the browser context, so it cannot access variables from outside its
scope.
https://angular.github.io/protractor/#/api?view=Protractor.prototype.addMockModule
browser.addMockModule('modName', function() {
angular.module('modName', []).value('foo', 'bar');
});
Problem: I am trying to pass another function Mockr to my mock module. I want to set and get a mock id.
steps.js
var mockData = require('../../mocks/data.js');
var Mockr = require('../../mocks/mockr.js');
var steps = function() {
this.Before(function(scenario, done) {
browser.addMockModule('httpBackEndMock', mockData.module, Mockr );
done();
});
};
module.exports = steps;
data.js
exports.module = function ( Mockr ) {
angular.module('httpBackEndMock', ['ngMockE2E'])
.run(function($httpBackend) {
// cannot access Mockr here...
// since this is in browser context scope,
// how can I access Mockr???
// like: Mockr.getMockId();
});
};
mockr.js
module.exports = {
id: 5,
setMockId: function(id) {
module.exports.id = id;
},
getMockId: function() {
return module.exports.id;
}
};

node.js unit testing mock dependency

I have a question on using proxyquire (or any other suggestions on how to test the following code)
If i have the following file to test:
var path = require('path');
module.exports = function (conf) {
var exported = {};
exported.getIssue = function (issueId, done) {
...
...
};
return exported;
};
How do i pass in the 'conf' variable while using proxyquire to mock 'path; var?
Is there any other way to do this if not using proxyquire?
You simply have to pass conf variable to the module/function required via proxyquire. Proxyquire has meaning to to do the same CommonJs require stuff, but with the possibility of mocking and stubing some modules. So you should act the same.
var pathMock = {
someMethod = function() {}
};
var confMock = {
someMethod = function() {}
};
spyOn(pathMock, 'someMethod').and.callThrough();
spyOn(confMock, 'someMethod').and.callThrough();
module = proxyquire('../path/to/module', {
path: pathMock
});
it('do some test', function(done) {
module(conf).getIssue();
expect(pathMock.someMethod).toHaveBeenCalled;
expect(confMock.someMethod).toHaveBeenCalled;
});

Node JS call a "local" function within module.exports

How do you call a function from within another function in a module.exports declaration?
I have MVC structure node js project and a controller called TestController.js. I want to access method within controller, but using this keyword gives below error:
cannot call method getName of undefined
"use strict"
module.exports = {
myName : function(req, res, next) {
// accessing method within controller
this.getName(data);
},
getName : function(data) {
// code
}
}
How do I access methods within controller?
I found the solution :-)
"use strict"
var self = module.exports = {
myName : function(req, res, next) {
// accessing method within controller
self.getName(data);
},
getName : function(data) {
// code
}
}
You can access the getName function trough module.exports. Like so:
"use strict"
module.exports = {
myName : function(req, res, next) {
// accessing method within controller
module.exports.getName(data);
},
getName : function(data) {
// code
}
}
Maybe you could do it like this. It reduce nesting. And all your export is done at the end of your file.
"use strict";
var _getName = function() {
return 'john';
};
var _myName = function() {
return _getName();
};
module.exports = {
getName : _getName,
myName : _myName
};
If you want to use the function locally AND in other files...
function myFunc(){
return 'got it'
}
module.exports.myFunc = myFunc;
I know the answer is already accepted, but I feel the need to add my two cents on the issue.
Node modules have a "Singletonic" nature, when inside the module, you are the module.
In my opinion, at least design pattern wise, inner module methods can be accessed more cleanly, without the need for this or a copy of self for that matter.
Using this, could be dangerous, if one happens to send the separate methods around and forgets to use .bind.
Using a copy of self, is redundant, we already are inside a Singleton behaving module, why keep a reference to yourself when you can avoid that?
Consider these instead:
Option 1
// using "exports."
exports.utilityMethod = (..args) => {
// do stuff with args
}
exports.doSomething = (someParam) => {
// this always refers to the module
// no matter what context you are in
exports.utility(someParam)
}
Option 2
// using module.exports
const utility = (..args) => {
// do stuff with args
}
const doSomething = (someParam) => {
// Inside the module, the utility method is available
// to all members
utility(someParam)
}
// either this
module.exports = {
utility,
doSomething,
}
// or
module.exports = {
customNameForUtility: utility,
customNameForDoSomething: doSomething
}
This works the same for es6 modules:
Option 1 (ES6)
export const utilityMethod = (..args) => {
// do stuff with args
}
export const doSomething = (someParam) => {
// this always refers to the module
// no matter what context you are in
utility(someParam)
}
Option 2 (ES6)
const utility = (..args) => {
// do stuff with args
}
const doSomething = (someParam) => {
// Inside the module, the utility method is available
// to all members
utility(someParam)
}
export default {
doSomething,
utility
}
// or
export {
doSomething,
utility
}
Again, this is just an opinion, but it looks cleaner, and is more consistent across different implementations, and not a single this/self is used.

Categories

Resources