Defining modules in UI5 - requirejs

I am trying to keep my code separated in modules. When I defined my first module I extended sap.ui.base.Object and it worked. My question is: Is it a must to extend sap.ui.base.Object when defining my own module? According to the API documentation I tried following example:
sap.ui.define([], function() {
// create a new class
var SomeClass = function();
// add methods to its prototype
SomeClass.prototype.foo = function() {
return "Foo";
}
// return the class as module value
return SomeClass;
});
I required this module inside my Component.js as dependency like this:
sap.ui.define([
"path/to/SomeClass"
], function (SomeClass) {
"use strict";
//var test = new SomeClass();
I always receive a syntax error:
failed to load '[...]/Component.js' from ./Component.js: Error: failed to load '[...]/module/SomeClass.js' from ./module/Service.js: SyntaxError: Unexpected token ;
Does anyone have an idea why this happens? Thanks!

We group code in modules like this for example:
jQuery.sap.declare("our.namespace.iscool.util.Navigation");
our.namespace.iscool.util.Navigation = {
to: function (pageId, context) {
// code here
}
// etc.
}
and call the function of the module like this in a controller
jQuery.sap.require("our.namespace.iscool.util.Navigation");
sap.ui.controller("our.namespace.iscool.Detail", {
// somewhere in this file comes this
handleNavButtonPress: function (evt) {
our.namespace.iscool.util.Navigation.navBackToMaster(
evt.getSource().getBindingContext()
);
},
}

Stupid mistake - missing curly brackets in the docs.
var someclass = function() {} ;

Related

When exporting a module like this, what happens?

I was looking up some database connection Google searches when I saw something that exported an instance of a module as such
const foo = () => {
// Do stuff
};
...
module.exports = foo();
I don't know what this is called but how does nodejs treat exporting a function invocation vs an object or the function itself (without calling it)?
Thank you
The foo function only gets called once no matter how many times you require the module.
This is very simplified explanation of what is happening behind the scenes in Node.js
// cache for modules
var modules = {};
// very simplified require function
function require(name) {
// check cache
if (modules[name])
// so if it has already been required it returns the cached result
return modules[name].module.exports;
// it will resolve path to the required module
// and loads the file content
// not showing here
var obj = { module: { exports: {}}};
// node will wrap the code in a function similar to bellow
function module(module, exports){
const foo = () => {
// Do stuff
};
...
module.exports = foo();
};
module(obj.module, obj.module.exports);
// and now cache it
modules[name] = obj;
return obj.module.exports;
}

Typescript with node.js giving "is not a constructor" error

I have a node.js application with two typescript files.
matchmanager.ts is defined as -
namespace LobbyService
{
export class MatchManager
{
constructor() { /*code*/ }
}
}
and main.ts which is defined as
namespace LobbyService
{
let matchManager: MatchManager = new MatchManager() ;
/* code */
}
I setup visual studio to output the files into a single JS file called lobbyservice.js
However, when i type
node lobbyservice.js
I get the following error -
TypeError: LobbyService.MatchManager is not a constructor
The generated file has this output -
var LobbyService;
(function (LobbyService) {
var matchManager = new LobbyService.MatchManager();
})(LobbyService || (LobbyService = {}));
var LobbyService;
(function (LobbyService) {
var MatchManager = (function () {
function MatchManager() {
console.log("created");
}
return MatchManager;
}());
LobbyService.MatchManager = MatchManager;
})(LobbyService || (LobbyService = {}));
This was working before, but for some odd reason it isn't now. Any thoughts?
Update - I managed to get a version of the lobbyservice.js that works. For some odd reason, Visual studio transforms one version of the file into the one above, and one into this -
var LobbyService;
(function (LobbyService) {
var MatchManager = (function () {
function MatchManager() {
console.log("created");
}
return MatchManager;
}());
LobbyService.MatchManager = MatchManager;
})(LobbyService || (LobbyService = {}));
var LobbyService;
(function (LobbyService) {
var matchManager = new LobbyService.MatchManager();
})(LobbyService || (LobbyService = {}));
//# sourceMappingURL=lobby.js.map
No clue as to why i'm getting two different outputs like that for the same source code. Both projects have the same module property of "none"
So user Elliott highlighted that indeed it's a know typescript compile quirk where the order of the output javascript file creates an issue.
to fix that, i had to add
/// <reference path="matchmanager.ts"/>
On my typescript files that used MatchManager class, even though they were on the same namespace and compiled ok. This forced the typescript compiler to create a workable javascript output.

JHipster generator: addMavenDependency is not defined

I'm trying to create a JHipster generator to setup Axon2 for the generated project.
In order to add a java library to the project I'using the function
addMavenDependency in the index.js,
try {
addMavenDependency('org.axonframework', 'axon-integration', '2.4.6','');
}catch (e) {
but I receive the following error:
ERROR!
Problem when adding the new libraries in your pom.xml
You need to add manually:
"org.axonframework:axon-integration": "2.4.6",
ReferenceError: addMavenDependency is not defined
Any help will be really appreciated.
You need to extend the BaseGenerator and call this.addMavenDependency().
Unless you are composing with another generator, then you can pass an object to be populated with the variables and functions being used by the generator like so:
const jhipsterVar = { moduleName: 'your-module' };
const jhipsterFunc = {};
module.exports = generator.extend({
initializing: {
compose() {
this.composeWith('other-module',
{ jhipsterVar, jhipsterFunc },
this.options.testmode ? { local: require.resolve('generator-jhipster/generators/modules') } : null
);
}
},
writing: {
jhipsterFunc.addMavenDependency('com.test', 'test', '1.0.0');
}
});

pass optional parameters to require()

so, I have this problem - and when I have a problem with JavaScript or node inevitably it is my coding that is the problem ;)
So at the risk of ridicule, this is the problem:
I have a module that has an optional parameter for config
Using the standard pattern, this is what I have:
module.exports = function(opts){
return {
// module instance
};
}
and in the calling code there is this
var foo = require('bar')({option: value})
if there are no options to pass, the code looks like this
var foo = require('bar')({})
which kinda looks ugly
so, I wanted to do this
var foo = require('bar')
which doesn't work, as the exports is a function call
so, to the meat of the issue
a) is there any way of achieving this lofty goal ?
b) is there a better pattern of passing parameters to a module ?
many thanks - and I hope that once the laughter has passed you will be able to send some help my way :)
Instead of removing the function call completely, you could make the options argument options to remove the need for an empty object:
module.exports = function(opts) {
opts = opts || {};
return {
// module instance
};
}
It doesn't completely remove the need for () but is better than ({}).
tldr: stick with require('foo')('bar');
There's no way to pass additional parameters to require. Here's the source code, notice how it only takes a single argument:
Module.prototype.require = function(path) {
assert(util.isString(path), 'path must be a string');
assert(path, 'missing path');
return Module._load(path, this);
};
If you really really really want to avoid ()(), you could try something like this:
b.js
'use strict';
module.exports = {
x: 'default',
configure: function (x) {
this.x = x;
},
doStuff: function () {
return 'x is ' + this.x;
}
};
a.js
'use strict';
var b = require('./b');
// Default config:
console.log(b.doStuff()); // 'x is default'
// Reconfigure:
b.configure(42);
console.log(b.doStuff()); // 'x is 42'
But I think it's uglier... stick with the original idea.

solving circular dependency in node using requirejs

I have been try out many suggestions I found googling for circular dependency in node and requirejs. Unfortunately, I'm not getting it to work. The try which is closed to a solution (I think) is below:
// run.js
var requirejs = require('requirejs');
requirejs.config({
baseUrl: __dirname,
nodeRequire: require
});
requirejs(['A'], function(A) {
var a = new A.Go();
console.log(a.toon())
});
// A.js
define(['B', 'exports'], function(B, exports) {
exports.Go = function() {
var b = new require('B').Ho();
var toon = function() {
return 'me tarzan';
};
return {
b: b,
toon: toon
}
};
});
// B.js
define(['A', 'exports'], function(A, exports) {
exports.Ho = function() {
var a = new require('A').Go();
var show = function() {
return 'you jane';
}
return {
a: a,
show: show
}
};
});
Running this code in node results in a RangeError: Maximum call stack size exceeded
We the dependency of B is removed from A.js, 'me tarzan' is returned
Any suggestion is appreciated!
Circular references are fine and not necessarily a symptom of bad design. You might argue that having many tiny modules could be equally detrimental because code/logic is scattered.
To avoid the dreaded TypeError: Object #<Object> has no method you need to take some care in how you initialize module.exports. I'm sure something similar applies when using requirejs in node, but I haven't used requirejs in node.
The problem is caused by node having an empty reference for the module. It is easily fixed by assigning a value to the exports before you call require.
function ModuleA() {
}
module.exports = ModuleA; // before you call require the export is initialized
var moduleB = require('./b'); //now b.js can safely include ModuleA
ModuleA.hello = function () {
console.log('hello!');
};
This sample is from https://coderwall.com/p/myzvmg where more info available.

Resources