How to trigger `exports.handler` in atom editor - node.js

This may be extremely silly.
I was using aws lambda functions for a while, and they usually start with exports.handler = (event, context, callback). AWS already has a test button where you can load in JSON and it tests it by providing JSON as an input to exports.handler, ad then from within the handler, formatting is done on the inputs, therse a bunch of console.logs() that are printed and so on.
I recently moved to atom editor, and moved all my code over from lambda. I am using Atom Runner to run my JS code.. however I realised when I run it, all I get is: Exited with code=0 in 0.745 seconds. Basically it isn't running at all.
How do I trigger exports.handler in Atom Editor? do I have to store JSON in a new file and call it in some way?

Lambda is wrapping your code, and knows to call that function .handler() when a request comes in. This is Lamba's contract with its users, but is not a universal thing. Right now Atom-Runner is just reading all of your code in, but then no functions are being called.
If you run node index.js (replace index with your filename) on the command line it will do the same thing Atom-Runner is doing.
You need a top level function call, for example adding exports.handler() at the very bottom of your file should work. If you want events, context, and callback to be defined you have to pass them yourself when you make that call (by reading in your JSON file or whatever you want).

Related

how to suppress output of a function in node/typescript

I have a typescript/node application where I am calling a 3rd-party function from a package that will output a string to the console. However, I want to know if it is possible to somehow suppress any kind of output (to the console/terminal) that this function will produce. I know that adding console.log = () => {} at the top of the file can do the job, but the linting rules (which I cannot change) of my group project state that calls to console.log are not allowed. Would anyone know of a more effective way of disabling output to console, without actually making reference to console?

Text in Bash terminal getting overwritten! Using JS, Node.js (npms are: inquirer, console.table, and mysql)

Short 10sec video of what is happening: https://drive.google.com/file/d/1YZccegry36sZIPxTawGjaQ4Sexw5zGpZ/view
I have a CLI app that asks a user for a selection, then returns a response from a mysql database. The CLI app is run in node.js and prompts questions with Inquirer.
However, after returning the table of information, the next prompt overwrites the table data, making it mostly unreadable. It should appear on its own lines beneath the rest of the data, not overlap. The functions that gather and return the data are asynchronous (they must be in order to loop), but I have tried it with just a short list of standard synchronous functions for testing purposes, and the same problem exists. I have tried it with and without console.table, and the prompt still overwrites the response, as a console table or object list.
I have enabled checkwinsize in Bash with
shopt -s checkwinsize
And it still persists.
Is it Bash? Is it a problem with Inquirer?
I was having this issue as well. In my .then method of my prompt I was using switch and case to determine what to console log depending on the users selection. Then at the bottom I had an if statement checking to if they selected 'Finish' if they didn't I called the prompt function again, which I named 'questionUser'.
That's where I was having the issue, calling questionUser again was overriding my console logs.
What I did was I wrapped the questionUser call in a setTimeout like this:
if(data.option !== 'Finish'){
setTimeout(() => {
questionUser();
}, 1000);
}
This worked for me and allowed my console log data to not get deleted.
Hopefully if anyone else is having this issue this helps, I couldn't find an answer to this specific question anywhere.

What is the proper way to return a JSON object to Alexa Smart Home or end AWS Lambda in NodeJS?

I have seen three ways to return a JSON object or end a Lambda function. My trigger is Smart Home Alexa.
I am using now is context.succeed(response_JSON);This one works for me. Even if this instructions is inside a nested function. The whole Lambda ends and return the response_JSON to Smart Home Alexa.
I have seen in other blogs that say callback(response_error,response_JSON). This one did not work for me. It did not return anything to Smart Home.
Others just uses the return response_JSON. I have not used this one.
I am using now is context.succeed(response_JSON);This one works for me. Even if this instructions is inside a nested function. The whole Lambda ends and return the response_JSON to Smart Home Alexa.
context.succeed()/fail() causes the Lambda function to terminate immediately. However, I have not seen this documented in the context object docs, so it may get deprecated in later Node versions (?).
I have seen in other blogs that say callback(response_error,response_JSON). This one did not work for me. It did not return anything to Smart Home.
This one probably doesn't work for you because by default Node.js waits for the event loop to be empty before executing the callback statement. This may be due to open network/database connection. As per the doc, set the context.callbackWaitsForEmptyEventLoop variable to false to send the response right away.
Others just uses the return response_JSON. I have not used this one.
This should be used with async handlers. Read more about async and non-async handlers here: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html

yargs (node module): command module files... parse the command, but without automatically executing the command's exports.handler code

I'm using yargs with command modules, i.e. separate file for each command, with each command file defining exports.command, exports.desc, exports.handler for its own command.
For 60% of my commands, the way it works by default is fine. But the other 40% I want to first connect to a database with TypeORM, which is async, and then only after the connection has been made, execute exports.handler wrapped inside a .then() so that it doesn't execute before the DB has connected.
The issue is that in my global entry file, as soon as all the global yargs options are defined, and I execute .argv for yargs to parse the command (which determines if it's a db or non-db command), it also executes exports.handler immediately, so I have no opportunity first connect to the database, and use .then to wrap the exports.handler command code (for the 40% of commands that need it).
I want to avoid having to add async code just for the db connection to every one of those 40% of command files. And also avoid connecting to the db for all 100% of commands, as 60% of them don't need it.
I was about to make major changes and no longer use yargs' command modules... but there must be an easier way to do this?
Is there a way to tell yargs that I want to parse the command but not execute exports.handler yet?
If I can just figure that out, then I can simply segregate the commands that need to be wrapped inside .then() and those that don't.

hunchentoot-based app in a lisp image (from buildapp) immediately returns

So I have an application using restas, based on hunchentoot.
At some point, I have the following function:
(defun main (args)
(declare (ignore args))
(set-config)
(restas:start '#:spa :port 8080))
(set-config) sets a few values related to database.
Anyway, I then use buildapp in the following way:
buildapp --output dist/spa --load-system spa --asdf-tree ~/quicklisp/ --entry spa::main --compress-core
Which works perfectly. The (set-config) function requires a config.json file to be present, and it indeed doesn't work when the file doesn't exist, so I know for sure that the application is correctly compiled.
When I run the generated binary however, the application immediately returns. Which means the HTTP server doesn't stay up.
I guess it's related to the fact that hunchentoot spawns a new thread, but it shouldn't stop the process, should it?
Also, I don't want to not use threads, i.e. I want the fact that each request is a separate thread.
So... I'm not sure exactly why it immediately returns. Why? And how to fix it?
I guess that you have to enter a main loop to keep the program running. The example at http://www.xach.com/lisp/buildapp/ uses the SBCL-specific (sb-impl::toplevel-repl nil).

Resources