Typescript AMD Module not returning anything - requirejs

I am exporting a simple function inside of a "log.ts" file:
export function message(s : string) {
console.log(s);
}
This is imported by a file ("MyController.ts") in the same directory:
import log = module("./log");
class MyController {
a : string = "aaa";
constructor () {
log.message("hello world");
}
}
When compiled, I get the following JS:
define(["require", "exports", "./log"], function(require, exports, __log__) {
var log = __log__;
var MyController = (function () {
function MyController() {
this.a = "aaa";
log.message("hello world");
}
return MyController;
})();
})
//# sourceMappingURL=MyController.js.map
This define function should return MyController. Because it does not, the callback inside this snippet does not get anything for the controller parameter:
require(["MyController"], function (controller) {
theRoute.controller = controller;
defer.resolve();
$rootScope.$apply();
});
I can fix this by manually adding the return inside of the call to define, but this is not a good workaround because the JS is being outputted by the TS compiler.
Am I doing something wrong or is this a bug in typescript?

You should write:
import log = module("./log");
export class MyController { // <--- 'export'
a : string = "aaa";
constructor () {
log.message("hello world");
}
}
And:
require(["MyController"], function (controller) {
theRoute.controller = new controller.MyController(); // <--
defer.resolve();
$rootScope.$apply();
});
Starting in 0.9.x you'll be able to write export = MyController; at the bottom of the .ts file to make the class be the top-level exported object.

Related

Nodejs Set a global function and call a nested function

My Main function
import AppLauncher from './Applauncher'
function Mainfunc() {
global.app= AppLauncher()
global.app.start('index')
}
AppLauncher.js
function AppLauncher() {
function start(opts){
console.log('functions start called with' + opts)
}
}
export default AppLauncher
I want to assign the AppLauncher function as global, and call the start function nested inside it
Constructors are the way to go. You can do something like this:
// AppLauncher.js
function AppLauncher() {
// run some code...
// notice `this`
this.start = function(opts) {
console.log('start function called with', opts);
}
}
export default AppLauncher;
In your main function, call it with the new keyword:
import AppLauncher from './AppLauncher';
function Mainfunc() {
global.app = new AppLauncher();
global.app.start('index');
}
Constructors can also be written as classes (you can use it the same way as in my last example):
class AppLauncher {
constructor() {
// Anything in here gets executed when once you create an object from this class with the `new` keyword
}
// Instead of `this` we add a method to the class:
start(opts) {
console.log('start function called with', opts);
}
}
export default AppLauncher;
More about constructors: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor
If you don't want to use a constructor, you can also return an object:
// AppLauncher.js
function AppLauncher() {
// Some code here...
return {
start(opts) {
console.log("function start called with", opts);
}
};
}
export default AppLauncher;
And you can use this just like you thought:
import AppLauncher from `./AppLauncher`;
function Mainfunc() {
global.app = AppLauncher();
global.app.start('index');
}
As a side note, it's conventional to call constructors with PascalCase, while regular functions are called with camelCase.

How to export object from module.exports?

I need to require a file passing a parameter, for this I used the following syntax:
module.exports = function(bot) {
const menu = new TelegrafInlineMenu(bot);
return menu;
};
the problem's that the code above export the function, I need to return the menu object, is there a way to do this?
I require the script using:
const menu = require('menu')(bot);
problem's that menu is a function not an object
function TelegrafInlineMenu(bot) {
// constructor
if (!(this instanceof TelegrafInlineMenu)) {
return new TelegrafInlineMenu(bot);
}
}
TelegrafInlineMenu.prototype.someFunction = function () {
// etc.
};
module.exports = TelegrafInlineMenu;

NodeJS: Can a static method call the constructor of the same class?

I've got a question: If I have a constructor in a class:
module.exports = class ClassA{
constructor(stuffA, stuffB) {
this.stuffA = stuffA;
this.stuffB = stuffB;
}
NonStaticMethod() {
console.log(this);
}
static StaticMethod(stuffA, stuffB) {
const element = new ClassA(stuffA, stuffB);
console.log(element)
element.NonStaticMethod();
});
}
};
So, the NonStaticMethod prints other information for the object than the StaticMethod. So two questions:
Can I call the constructor from a static method from the same class?
What should be the correct way of calling the non-static method from the static method?
The following code prints "true", so in NonStaticMethod this.stuffA rely correctly on value defined in constructor:
class ClassA{
constructor(stuffA, stuffB) {
this.stuffA = stuffA;
this.stuffB = stuffB;
}
NonStaticMethod() {
console.log(this.stuffA === "a");
}
static StaticMethod(stuffA, stuffB) {
const element = new ClassA(stuffA, stuffB);
element.NonStaticMethod();
};
}
ClassA.StaticMethod("a","b")

How to create node.js module using Typescript

The very simple module that I've created to test the viability of this endeavor. Here is the beginning of SPServerApp.ts:
class SPServerApp {
public AllUsersDict: any;
public AllRoomsDict: any;
constructor () {
this.AllUsersDict = {};
this.AllRoomsDict = {};
}
}
module.exports = SPServerApp();
Then in my app, I have this require statement:
var serverapp = require('./SPServerApp');
I then try to access one of the dictionaries like so:
serverapp.AllUsersDict.hasOwnProperty(nickname)
But get the error:
TypeError: Cannot read property 'hasOwnProperty' of undefined
Can anybody see what I am doing wrong here?
Thanks, E.
The problem is that you forgot the 'new' keyword when calling the constructor. The line should read:
module.exports = new SPServerApp();
If you don't use new your constructor will be treated as a normal function and will just return undefined (since you did not return anything explicitly). Also 'this' will not point to what you expect within the constructor.
Omitting new in Node is actually quite common. But for this to work you have to explicitly guard against new-less calls in the constructor like so:
constructor () {
if (! (this instanceof SPServerApp)) {
return new SPServerApp();
}
this.AllUsersDict = {};
this.AllRoomsDict = {};
}
BTW, in TypeScript you can also use module syntax. The TS compiler will translate this into the export/require statements. With ES6 style modules your example would look like this:
export class SPServerApp {
public AllUsersDict: any;
public AllRoomsDict: any;
constructor () {
this.AllUsersDict = {};
this.AllRoomsDict = {};
}
}
export var serverapp = new SPServerApp();
In your other TS file you just import:
import { serverapp } from './SPServerApp';
serverapp.AllUsersDict.hasOwnProperty('something');

NodeJS module instances

I have the following code. I want to use the prototype keyword as I want to call method functions and not class methods, why does this give me an error? If I remove the prototype call this works. How can I write this code so I'm able to use instances not class methods?
//app.js
var MyTest = require('./MyTest')
var myTestInstance = new MyTest()
myTestInstance.testFunction(function(reply){
console.log(reply)
})
//MyTest.js
module.exports = function() {
function MyTest() {}
MyTest.prototype.testFunction = function(cb) {
cb('hello')
}
return MyTest
}
to have your app.js working as it is you need to replace the content of MyTest.js with the following:
function MyTest() {}
MyTest.prototype.testFunction = function(cb) {
cb('hello');
};
module.exports = MyTest;
As you have it in app.js you need a constructor and not a factory function.

Resources