Importing libraries using "new Function" syntax - javascript

In an API response that I'm integrating with, I receive JS code inside a JSON that I need to execute at run-time.
For that, I normally use the new Function() statement. While for most cases this works just fine, there are some other cases that contain references to external libraries such as moment or lodash.
Here's an example of such JS string:
{
...
"calculateValue": "value = moment().diff(moment(row.DateOfBirth), 'years');"
...
}
So I create a function by doing new Function('row', 'value = moment().diff(moment(row.DateOfBirth), 'years');')
and then execute it.
However, the error I'm getting is
[ReferenceError: moment is not defined]
Logically, I tried adding a reference to moment in the file where the function is being executed and also tried concatenating the import statement to the string without any luck.
Is there a way of importing external libraries using the "new Function" syntax or using "eval"?
Please bear in mind that I receive these JS strings dynamically by requesting data from a server an cannot actually write those.

Related

Uncaught ReferenceError:some_string is not defined

In controller class, I have added
model.addObject("hostname", hostname);
and tried to catch it in my jsp page with
var hostname=<%=request.getAttribute("hostname")%> ;
Yet, this is throwing error
Uncaught ReferenceError:**some_string** is not defined
What can be done to avoid this?
Remember: You are not passing a variable from one program to another, you are programmatically generating JavaScript source code from JSP.
some_string is a variable name, but not one you've declared, so you get a ReferenceError.
You need to generate the JS source code which gives you the result you need.
For most cases, due to the compatibility between JS and JSON, you can use a JSON stringifier to generate the source code that creates your values (this is a good generic solution as it will do The Right Thing with quotes, new lines, arrays, etc).
Be careful as if the string contains </script> you need to escape the / to prevent it terminating the <script> element. Some JSON serializers will do this by default. I don't know if Java's will.

Pass function to Pug template to be used via callback in Javascript frontend

I'm trying to pass a function (timeAgo module) to my Pug template to be used in my frontend Javascript during a callback.
However no combination of methods I try can get the module to work during a callback. If I use it while I compile the frontend it works fine of course, but I can't load the module as a function in a script tag such that I can use it again.
So:
p.balance-text #{timeAgo.format(new Date(story.publishedAt))}
Works fine, but how can I do something like:
script.
// this allows me to use it to format dates received via an AJAX request
var timeAgo = #{timeAgo}
I've also tried things like using JSON.stringify to pass it to the frontend but nothing seems to work. Is it possible with pug? Thanks
You can't.
You are generating HTML source code. So everything needs to be able to be cast to a string.
I've also tried things like using JSON.stringify
This is also why JSON doesn't have a function data type.
Generate a <script> element with a src attribute that loads the module in a static file. (If it is an ES6 module, then either use <script type="module"> and import it instead, or use Webpack).

compile time required function parameter checking

Is there a best practice way of enforcing parameters in functions at build time vs runtime? For example if i have following function:
function localize(strings, key, ...args) {
return ...
}
and I called it as such:
var result = localize('myKey')
I did not pass the first parameter ('strings'). I would like to throw a compile error and not wait until runtime to get the error.
Because Javascript is not compiled, and dynamically typed, there is no way to enforce the contract in your example except at runtime.
However, you can use a build system like Typescript, Flow, etc, to add type annotations to your code. These require a compilation step BUT the issue you have in your example would be caught by both during that step.
Without that, there is no way to get what you want as far as I know. The best you could do in vanilla javascript is to validate the arguments you are given inside the localize function, and use logs/errors so that you can easily identify the issue when you test your code locally. The important bit here is that without actually running your code, there is no way to catch the error in your example using vanilla JS.

What's the best way to handle Eclipse errors on CouchDB Map/Reduce JavaScript functions?

As noted in Where to write and store mongoDB map/reduce functions in java project - Eclipse doesn't like a JavaScript (.js) file to only contain the following:
function(doc) {
if(doc.somekey) emit(doc._id, doc);
}
The keyword function is marked with an error:
Syntax error on token "function", Identifier expected after this token
This form is used in MapReduce, but perhaps it's not exactly valid JavaScript (I'm not a lawyer). Is there any way to allow this form?
edit it looks like it's a function expression instead of a function statement. ( MDN, ECMA-262 )
Non-solution: "Just add a function name" according to https://stackoverflow.com/a/11258388/185799 it seems that it's not important to economize on the size of these functions. However, adding a function name results in: {"error":"compilation_error","reason":"Compilation of the map function in the 'myView' view failed: Expression does not eval to a function."}
Possible solution? Add a function name or "module.exports = " at the top, and then remove it during a build phase, using grunt/gulp/yeoman or something related.
For now, what I am actually doing is using the literal form function anonymous(... and then doing a string replace just before calling synchronizeWithDb() to replace function anonymous( with function(. This doesn't answer my question, but works around it.
You have three bad options:
You can ignore the error since CouchDB can process this file (it will wrap it later to make it valid).
You can change the file extension but then you lose syntax highlight, code completion and error checks.
You can delete the error in the error view. It will stay deleted until you change the file the next time or you do a full build.
You may be able to configure Eclipse to stop validating the file.
There are two ways to implement #4:
You can ignore the resource. That makes this file invisible to Eclipse and all plugins. Which means you can't edit it anymore inside of Eclipse. Use Resource Filters for that.
You can check the per-project preferences for Validation rules for JavaScript. Maybe you can exclude the file.

How to go about utilizing acorn.js in another .js file?

I'm trying to write a Javascript translator using a Javascript parser called "acorn.js." I'm writing my code in Sublime using a Node build system. Calling the following line:
require("./acorn.js");
produces no errors, but whenever I attempt to access any functions within that file, an undefined error is thrown. Is there any way I can import or reference this library to gain access to its functions without having to utilize a JQuery import or something of the like?
Here is the answer:
var test = acorn.parse("var x;");
And if you're using this specific library, what is returned is an AST of the contents of what you parse. In this case, it's the string "var x;".
You have to assign the imported module to a variable. For ex :
var acorn = require("./acorn.js");
And access the methods from that variable :
acorn.parse(in,out);

Categories

Resources