Crash when trying to load a file using Node's repl library - node.js

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.

Related

NodeJS is not running imported function

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'

how to debug a node file that uses CGI

I have a node app that reads data to be processed from the CGI (common gate interface). This is data is test1.txt so to run my file I type in the terminal:
node app.js<test1.txt
I want to debug this code with vscode but to run it needs the data from the file. Notice that "<" is not a parameter, it reads the content of test1.txt and it's put in app.js as if they were typed.
I paste code sample here which read a line of text of test2.txt and converts the spaced number to an array of integers. This require an environment variable OUTPUT_PATH to set to "out.txt" for example. I should also say what I am trying to do is to run challenges of "hacker rank" in my local PC to be able to debug my code using vscode.
'use strict';
const fs = require('fs');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', function(inputStdin) {
inputString += inputStdin;
});
process.stdin.on('end', function() {
inputString = inputString.split('\n');
main();
});
function readLine() {
return inputString[currentLine++];
}
// -------------------------------------------------
function app(arr) {
console.log(JSON.stringify(arr));
}
function main() {
const ws = fs.createWriteStream(process.env.OUTPUT_PATH);
const arr = readLine().replace(/\s+$/g, '').split(' ').map(queriesTemp => parseInt(queriesTemp, 10));
const result = app(arr);
ws.write(result + '\n');
ws.end();
}

nodejs REPL output on same line

I'm building a CLI app with nodejs with native REPL. A dumb sample is:
const repl = require('repl')
const myApp = require('myApp')
repl.start({
eval: (input, context, filename, callback) => {
const result = myApp(input)
callback(null, result)
},
writer: (result) => result
? 'my result: ' + result
: '' // <--- empty result
})
Everything is fine, but a newline is created for every response of the app. I'd like to override this behavior, and decide whether to create a new line or not.
Example
Let's pretend the app to be a calculator:
$ node index.js
add 5
add 3
result
8
Because add command doesn't have any result, a new command should be inserted in the very next line. However, what I'm getting from the above code is:
$ node index.js
add 5
add 3
result
8
with an empty line added after any 0add call.
How can I prevent this?
So I found out there's a parameter I could set, ignoreUndefined. If true, when you call callback(null, undefined) (empty result case), it won't add a new line.
Thus, in the above example:
const repl = require('repl')
const myApp = require('myApp')
repl.start({
ignoreUndefined: true,
eval: (input, context, filename, callback) => {
const result = myApp(input)
callback(null, result)
},
writer: (result) => result
? 'my result: ' + result
: undefined // <--- empty result
})
docs: https://nodejs.org/api/repl.html
similar question: node.js REPL "undefined"

NodeJs : why my Writablestream does not close before end of program?

I have a NodeJS script that I use to write JSON objects to file :
var reWriteCodes = function(arrayCodes, pathFileCodes, fs, typereWriteCodes, cb) {
console.log("message : "+ typereWriteCodes);
var codesStream = fs.createWriteStream(pathFileCodes, {'flags': 'w'});
codesStream.on('finish', () => {
console.log("the stream is closed")
if (typereWriteCodes === 0) {
cb();
}
});
var jsonToWrite = { "liste_codes" : arrayCodes};
codesStream.write(JSON.stringify(jsonToWrite));
codesStream.end();
}
This function is called twiced (first with typereWriteCodes = 0 then with typereWriteCodes = 1, inside the callback function : cb) with two different files.
The first call ends fine, my file is saved and the message "the stream is closed" displays in the console. But in the second call (which is the last operation of the program), my file is not saved correctly (the file is empty) and the message "the stream is closed" is not triggerd. Also, I get this message :
events.js:141
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, open ''
at Error (native)
I have the feeling that the app is closing before the stream could end correctly ... But I do not know how I can do this correctly. Could you help me with this issue ? Any help appreciated.

Getting class level variables in a http.createServer requestListener

I have the following CoffeeScript code example:
class TestClass
constructor: () ->
#list = new Object()
addToList: (key, value) ->
#list[key] = value
printList: () ->
console.log("This is printed from printList:", #list)
startHttp: () ->
http = require("http")
http.createServer(#printList).listen(8080)
test = new TestClass()
test.addToList("key", "value")
test.printList()
test.startHttp()
When I run the code, and make a HTTP request to 127.0.0.1:8080, I expect to get the following output:
This is printed from printList: { key: 'value' }
This is printed from printList: { key: 'value' }
But I get the following instead:
This is printed from printList: { key: 'value' }
This is printed from printList: undefined
Why is it the printList function can't access the list variable when it is called from the HTTP server?
I am using Node.js v0.6.1 and CoffeeScript v1.1.3.
printList: () =>
console.log("This is printed from printList:", #list)
Use => to bind the value of this to the function so it "works" as you expect.
Disclaimer: instances might break. Coffeescript is black magic for all I care.
What you really want to do is invoke the method on the correct object
that = this
http.createServer(->
that.printList()
).listen 8080
Or in plain javascript.
var that = this;
http.createServer(function () {
that.printList();
}).listen(8080);

Resources