I have an index.js where I import a module:
const msg = require('../server/email/sendMail');
console.log(msg);
In my sendMail file I have:
// sendMail.js
function main() {
return 'message'
}
module.exports = {main};
When I run the index.js file I get:
{ main: [Function: main] }
I expected the string message to be shown in the log.
To run a function you need to add () at the end of the function name:
msg()
So you need to do:
console.log(msg())
On the other hand, to pass the function around as a variable (not run it) instead of the result of the function you don't add the ():
let a = msg
let b = msg()
// a is now the function
// b is the string "message"
console.log(a()) // prints 'message'
Related
In our team's project, I encountered a problem that hasn't been solved yet.
It is about unit test. I simplified the code like below. Also add an online demo below
// this is temp.js
// when run temp.test.js, b is assigned undefined
// because process.env.TEMP is undefined at that time
const b = `${process.env.TEMP}`;
// console.log(process.env.TEMP); // is undefined
export function temp(a) {
// if b is defined in here, process.env.TEMP works
// const b = `${process.env.TEMP}`;
return b;
}
// export other function, also use b
// this is temp.test.js
import { temp } from "./temp";
process.env = {
TEMP: "temp"
};
describe("temp", () => {
test("test temp", () => {
// console.log("temp test.js: ", process.env.TEMP); // is temp
expect(temp()).toBe("undefined"); // pass
// expect(temp()).toBe("temp"); // not pass, hope it can works
});
});
demo on codesandbox
I wonder how to test temp.js. Thanks for your help!
enter image description here
I have two files with differents functions in a NodeJS program, and each files require the other file to get function inside.
On the seond file included by require, the required element is empty.
On index.js
const bar = require('./bar.js');
const foo = require('./foo.js');
foo.sayHello();
On foo.js
const bar = require('./bar.js');
var sayHello = function(){
var name = bar.getName();
console.log('Hello '+name);
}
module.exports = {
sayHello : sayHello
}
On bar.js
const foo = require('./foo.js');
var getName = function(){
return 'Paul';
}
module.exports = {
getName : getName
}
When we lauch this code, the error bellow is displyed :
TypeError: bar.getName is not a function
And if I make a console.log(bar); in foo.js, the result is an empty object {}
To solve this problem we can include the foo.js file first, but in this case, it is the foo object in the bar.js file that will be empty.
Is it impossible to make crossover required with two files?
I am building an application where memory is very costly. I have imported modules and constants as shown below in multiple files. Does it cause memory leak?. My understanding is that require('module_name') is singleton but if we use it along with object destructuring then new variables are created for each require. Now if below style is used throughout the project then its too much variable declaration right?
user_controller.js
const { createUser, updateUser } = require('user_manager'); // importing functions from user module
const { APPLICATION: USER_LIMIT } = require('config'); // importing constants from config file
user_manager.js
const createUser = () {
// Some code here
}
const updateUser = () {
// Some code here
}
module.exports = {
createUser,
updateUser
}
config.js
module.exports = {
APPLICATION: {
USER_LIMIT: 10,
// Many such constants.
}
}
Small experiment on object destructuing:
index.js
var { name, getName } = require('./module1')
var module1 = require('./module1')
var module2 = require('./module2');
console.log(`local name Before: ${name}`);
console.log(`local name Before: ${getName()}`);
name = "Alex";
console.log(`local name After: ${name}`);
console.log(`local name After: ${getName()}`);
console.log(`Module1 name After: ${module1.name}`);
console.log(`Module1 name After: ${module1.getName()}`);
console.log(`Module2 name Before: ${module2.name}`);
console.log(`Module2 name Before: ${module2.getName()}`);
module2.name = "Ajax";
console.log(`Module2 name After: ${module2.name}`);
console.log(`Module2 name After: ${module2.getName()}`);
module1.js
const Module1 = require("../require_vs_new/Module1");
module.exports = {
name: "Dheemanth",
getName: function () {
return this.name;
}
}
module2.js
module.exports = {
name: "Dheemanth",
getName: function () {
return this.name;
}
}
Output
No, it's behaving normally:
The destructured "name" variable has "Dheemanth" value until you override it with "Alex".
The destructured "getName" variable is a function where "this" refers to nothing so the returned value is undefined.
Your module1 tests behaves normally, "getName" is attached to it so "this" is defined.
Your module2 tests also behaves normally and you are able to change the returned value by overwriting "module.name".
You may want to read about the this keyword that it a bit special in javascript.
I am getting a crash at the indicated point below when the code attempts to load a file. The file contents are read and displayed on the console. But when the line
app.ports.receiveData.send(data.toString());
is (tried to) execute, the code crashes. I've attached the error message below the code. The JS code here is used to run some Elm code "headless". The app.ports... function call is supposed send data back to the Elm app. (The Elm Code is further down).
JS CODE:
const repl = require('repl');
const fs = require('fs')
// Link to Elm code
var Elm = require('./main').Elm;
var main = Elm.Tool.init();
// Eval function for the repl
function eval(cmd, _, _, callback) {
main.ports.put.subscribe(
function putCallback (data) {
main.ports.put.unsubscribe(putCallback)
callback(null, data)
}
)
main.ports.get.send(cmd)
}
main.ports.sendFileName.subscribe(function(data) {
var path = data
// console.log(path)
fs.readFile(path, { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data.toString())
// Crash on next line !!!!
app.ports.receiveData.send(data.toString());
})
});
function myWriter(output) {
return output
}
console.log("\nType 'h' for help\n")
repl.start({ prompt: '> ', eval: eval, writer: myWriter});
Elm CODE
Here are the parts the Elm code that are relevant.
This code is called when the user wants to load a file.
loadFileCmd : String -> Cmd msg
loadFileCmd fileName =
sendFileName (E.string <| "./source/" ++ fileName)
These are the ports used to communicate with JS
port get : (String -> msg) -> Sub msg
port put : String -> Cmd msg
port sendFileName : E.Value -> Cmd msg
port receiveData : (E.Value -> msg) -> Sub msg
The get port listens for commands the user gives to the repl and gives these commands to Elm to process. The put port sends data that Elm computes to the repl.
The sendFileName port sends a file path to the repl. The receiveData port listens for the file contents. (But we crash before this can happen).
Here are the subscriptions:
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.batch [ Command.get Input, Command.receiveData ReceiveFileContents ]
ERROR MESSAGE:
repl.js:573
const lines = errStack.split(/(?<=\n)/);
^
TypeError: errStack.split is not a function
at Domain.debugDomainError (repl.js:573:30)
at Domain.emit (events.js:321:20)
at Domain.EventEmitter.emit (domain.js:485:12)
at Domain._errorHandler (domain.js:253:23)
at Object.<anonymous> (domain.js:156:29)
at process._fatalException (internal/process/execution.js:164:29)
From the comments, the answer was to replace the line
app.ports.receiveData.send(data.toString());
with
main.ports.receiveData.send(data.toString());
as the Elm app is named main, not app.
I was watching a course that showed how to make an console.log with custom configs, like the color or depending on your env mode, you show the log or not.
But i keep getting the error TypeError: Converting circular structure to JSON
and I don't know why this is happening and how to solve it.
In the course, that works fine, but it doesn't to me.
node version => v8.11.2
require('colors')
const _ = require('lodash')
const config = require('../config/config')
const noop = () => { }
const consoleLog = config.logging ? console.log.bind(console) : noop
const logger = {
log: () => {
const args = _.toArray(arguments)
.map(arg => {
if (typeof arg === 'object') {
let str = JSON.stringify(arg, 2)
return str.magenta
} else {
arg += ''
return arg.magenta
}
})
consoleLog.apply(console, args)
}
}
module.exports = logger
Edit1: arguments can be anything, since logger will be used to log things with different colors in the console.
logger.log('some thing you want to log')
logger.log() is an arrow function, so arguments are not arguments of this function (see Arrow functions: No binding of arguments), but arguments of a parent function, in this case — Node.js wrapper function that compiles modules and has arguments with circular dependencies.
Try to use common function here:
const logger = {
log() {
// ...
}
};