How to export object from module.exports? - node.js

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;

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.

Cannot call function in the same class

I defined a class called Plan. Here is the code:
class Plan {
async getPlanText(ctx) {
return await this.getPlanDetails(ctx);
}
async getPlanDetails(ctx) {
return ...
}
}
exports.Plan = Plan;
I get:
this.getPlanDetails is not a function
What I did wrong?
I used the Plan class in this way:
const { Plan } = require('./controllers/plan.controller');
let planController = new Plan();
console.log(planController.getPlanText('my context'));
try this. Basically you need to bind the function to a class while passing so it knows where to get the dependencies from. You can read more here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
const planController = new Plan();
const menu = new TelegraphInlineMenu(planController.getPlanText.bind(planController))

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

ES6, PreloadJS and scope

In PreloadJS' callback functions I'm losing scope. Have tried different methods such as an arrow function (which aren't valid on the highest level etc... Any tips? (sorry for the malformed code block (class defenition etc), still getting used to this editor, trust me, all is working code)...
import Navigation from './Navigation'
import ajax from "./Ajax";
import Helper from "./Helper";
let preload = null;
export default class Page{
constructor(){
this.preload = new createjs.LoadQueue();
this.preload.addEventListener("fileprogress", this.handleFileProgress);
this.preload.addEventListener("fileload", this.handleFileComplete);
}
initPage(_arg = []){
this.buildPage(this.thePage);
}
buildPage(_content){
this.loadImage(item.featured_image_thumbnail_url);
}
handleFileComplete(event){
console.log(event);
console.log(this); // undefined
let el = document.getElementById('heroImage');
let loader = el.getElementsByClassName('loader')[0];
this.showPage(); // cannot read property showPage of undefined
}
// small arrow test, doesn't seem valid
//handleFileComplete = (event) =>{
// this.showPage();
//}
handleFileProgress(event){
let hero = document.getElementById('heroImage')
let loader = hero.getElementsByClassName('loader')[0];
}
loadImage(_img){
let el = document.getElementById('heroImage');
let loader = el.getElementsByClassName('loader')[0];
let loadManifest = [
{
id: 'pat',
src: _img,
scope: this
}];
this.preload.loadManifest(loadManifest, true);
}
showPage(){
//Helper.removeClass(document.getElementById('mytest','hidden'));
}
}
Ok, update after only 5 min....
Addded an arrow function as a variable and passed that on to the event listener. This is not my preferred way but it does work though...
constructor(){
let handleFileCompleted = (event) => {
this.showPage(event)
}
this.preload = new createjs.LoadQueue();
this.preload.addEventListener("fileprogress", this.handleFileProgress);
this.preload.addEventListener("fileload", handleFileCompleted);
}
showPage(event){
console.log('I'm now reachable!');
console.log(event); // fileload event
}
Perhaps this can help anybody out.
Still interested to see if there's a better way though...

Typescript AMD Module not returning anything

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.

Resources