Using third party js libraries with Jint - javascript

I'm working on a feature where user defined, anonymous, javascript functions retrieved from a database need to be executed server side in the context of ASP.Net application.
I'm evaluating Jint for this purpose (Latest version from NuGet). I have been able to run functions that do basic operations and return values without an issue as below.
public void Do()
{
var jint = new Engine();
var add = jint.Execute(#"var f = " + GetJsFunction()).GetValue("f");
var value = add.Invoke(5, 4);
Console.Write("Result: " + value);
}
private string GetJsFunction()
{
return "function (x,y) {" +
" return x+y;" +
"}";
}
My question is whether Jint facilitates the execution of javascript functions which uses third party libraries like lodash? If so, how would I go about making the Jint engine aware of it (i.e third party library)?
An example would be the execution of following function.
private string GetFunction()
{
return "function (valueJson) { " +
" var value = JSON.parse(valueJson);" +
" var poi = _.find(value,{'Name' : 'Mike'});" +
" return poi; " +
"}";
}
Thanks a lot in advance.

I think I have figured this out. It's no different to executing a custom function. You just read the third party library from a file (project resource) and invoke execute on Jint engine. See below;
private void ImportLibrary(Engine jint, string file)
{
const string prefix = "JintApp.Lib."; //Project location where libraries like lodash are located
var assembly = Assembly.GetExecutingAssembly();
var scriptPath = prefix + file; //file is the name of the library file
using (var stream = assembly.GetManifestResourceStream(scriptPath))
{
if (stream != null)
{
using (var sr = new StreamReader(stream))
{
var source = sr.ReadToEnd();
jint.Execute(source);
}
}
}
}
We can call this function for all the third party libraries that needs to be added.

Related

iterating and extracting data from xml in javascript on mirth

I'm using mirth connect 3.7, java version 1.8. i am new to both mirth and javascript. I have set up a channel destination to a javascript writer to get data out of xml files inserted into a mysql db. a sample section of xml file as follows:
...
<DG1>
<DG1.1>
<DG1.1.1>1</DG1.1.1>
</DG1.1>
<DG1.2>
<DG1.2.1>I10</DG1.2.1>
</DG1.2>
<DG1.3>
<DG1.3.1>R10.9</DG1.3.1>
</DG1.3>
<DG1.4>
<DG1.4.1>UNSPECIFIED ABDOMINAL PAIN</DG1.4.1>
</DG1.4>
<DG1.5/>
<DG1.6>
<DG1.6.1>A</DG1.6.1>
</DG1.6>
<DG1.7/>
<DG1.8>
<DG1.8.1>391</DG1.8.1>
</DG1.8>
<DG1.9/>
<DG1.10/>
<DG1.11>
<DG1.11.1>4252.21</DG1.11.1>
</DG1.11>
<DG1.12/>
<DG1.13/>
<DG1.14/>
<DG1.15/>
<DG1.16/>
<DG1.17/>
<DG1.18>
<DG1.18.1>N</DG1.18.1>
</DG1.18>
</DG1>
<DG1>
<DG1.1>
<DG1.1.1>2</DG1.1.1>
</DG1.1>
<DG1.2>
<DG1.2.1>I10</DG1.2.1>
</DG1.2>
<DG1.3>
<DG1.3.1>R10.9</DG1.3.1>
</DG1.3>
<DG1.4>
<DG1.4.1>UNSPECIFIED ABDOMINAL PAIN</DG1.4.1>
</DG1.4>
<DG1.5/>
<DG1.6>
<DG1.6.1>A</DG1.6.1>
</DG1.6>
<DG1.7/>
<DG1.8>
<DG1.8.1>391</DG1.8.1>
</DG1.8>
<DG1.9/>
<DG1.10/>
<DG1.11>
<DG1.11.1>4252.21</DG1.11.1>
</DG1.11>
<DG1.12/>
<DG1.13/>
<DG1.14/>
<DG1.15/>
<DG1.16/>
<DG1.17/>
<DG1.18>
<DG1.18.1>N</DG1.18.1>
</DG1.18>
</DG1>
...
I am trying to get the datapoints out of the xml iteratively so i can insert these diagnosis codes in a mysql table. my script at this point:
try {
var dbConn = DatabaseConnectionFactory.createDatabaseConnection ('com.mysql.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/adt', 'xxx', 'xxx');
var xml = new XML(connectorMessage.getEncodedData());
var myNodeList = xml.querySelectorAll("DG1");
for (i = 0; i < myNodelist.length; i++) {
var myQuery = 'INSERT INTO adt.diagnosis (AcctNum, MRN, ICD10) VALUES ("'+ $('AcctNum') + '", "' + $('MedRecNum') + '", "' + myNodelist[i]['DG1.3']['DG1.3.1'] + '")';
//do something with myVar to get a query...
dbConn.executeUpdate(myQuery);
}
} catch (ex) {
//handle any exceptions...
}
it runs without exceptions but i am not capturing the intended data obviously. Again, new to javascript, mirth and parsing xml. Questions:
obviously, i'm referencing the data points inappropriately, what is the nomenclature in javascript?
is there a dev environment in mirth that i can step through code and better troubleshoot?
are there any good recommended resources for javascript and xml as it pertains to mirth?
Mirth uses Mozilla Rhino for its Javascript engine. Rhino uses a deprecated standard called e4x for XML processing. If you search Google for e4x you'll find several pages at developer.mozilla.org with scary "obsolete" banners everywhere that can be helpful. The mirth user guide is very detailed when it comes to workflow within mirth.
https://github.com/mozilla/rhino
https://web.archive.org/web/20181120184304/https://wso2.com/project/mashup/0.2/docs/e4xquickstart.html (another good e4x resource)
https://www.nextgen.com/products-and-services/NextGen-Connect-Integration-Engine-Downloads (for the user guide)
I'm surprised querySelectorAll wasn't throwing an error. With minimal changes to your code:
try {
var dbConn = DatabaseConnectionFactory.createDatabaseConnection ('com.mysql.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/adt', 'xxx', 'xxx');
var xml = new XML(connectorMessage.getEncodedData());
// This should work, but is not typically how hl7 segments are accessed. Would need to see more than a segment for typical usage.
var myNodeList = xml.descendants("DG1"); // returns type XMLList
// length is a function instead of property on XMLList objects
for (i = 0; i < myNodelist.length(); i++) {
var myQuery = 'INSERT INTO adt.diagnosis (AcctNum, MRN, ICD10) VALUES ("'+ $('AcctNum') + '", "' + $('MedRecNum') + '", "' + myNodelist[i]['DG1.3']['DG1.3.1'] + '")';
dbConn.executeUpdate(myQuery);
}
} catch (ex) {
//handle any exceptions...
}
Using a for each loop and parameterized sql statement:
try {
var dbConn = DatabaseConnectionFactory.createDatabaseConnection ('com.mysql.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/adt', 'xxx', 'xxx');
var xml = new XML(connectorMessage.getEncodedData());
var myQuery = 'INSERT INTO adt.diagnosis (AcctNum, MRN, ICD10) VALUES (?, ?, ?)';
for each (var dg1 in xml.descendants('DG1')) {
dbConn.executeUpdate(myQuery, new java.util.ArrayList([$('AcctNum'), $('MedRecNum'), dg1['DG1.3']['DG1.3.1'].toString()]));
}
} catch (ex) {
//handle any exceptions...
}
You'll want a finally block after your try to close your database connection. If you remove the catch block, mirth will automatically set the message status to ERROR, write the exception to the server log, and fire an event which you can act on with a defined alert. That's usually easier than trying to handle the exception yourself.
Hi this is not quite right.
First ensure your data type is HL7.
Then do this (this is for insurance but you get the idea)
for each ( in1 in msg['IN1']) {
var effdate = in1['IN1.12']['IN1.12.1'];
// etc
}

ASP.NET (UserControl) Syntax Error for server-side variable

I have two different variable which are defined in Server-side, Visual studio says me "The name 'PopupShowDelay' does not exist in the current context" and "The name 'QuotedTimeOutUrl' does not exist in the current context"
Javascript:
var schedulePopup = function() {
stopTimers();
var myVar = '<%= PopupShowDelay %>';
_popupTimer = window.setTimeout(showPopup, myVar);
};
Server-Side:
public int PopupShowDelay
{
get { return 60000 * (Session.Timeout - 2); }
}
public string QuotedTimeOutUrl
{
get { return '"' + GetEntry().BasarSettings.Where(a => a.Ad == "WebApplication").Select(a => a.Deger).FirstOrDefault() + '"'; }
}
Ps: Code is working well, problem is just VS gives me an error.
Microsoft has been release 15.4.2 version of visual studio for solve thi issue.

Nashorn binding issue

I have a java class like below
public class StaticBean {
public static String returnString(int num){
String json = "[{\"name\" : \"John Doe\", \"age\" : 30}]";
return json;
}
}
In the below test, i have two engine instances.
Upon execution, i see that it is not possible to copy the bindings instance onto another and use it for execution in the same engine or different engine. Even if i do copy, the results doesn't match with the ones i get if i use the same engine/binding.
#Test
public void testParsingStringObjects() {
Bindings b = engine.createBindings();
b.put("ndb", getBindingObject(StaticBean.class, engine));
engine.setBindings(b, ScriptContext.ENGINE_SCOPE);
String source = "print('Definition in engine instance 1');"
+ "var SysU = {};\n"
+ "SysU.returnObject = function returnObjectJS(){\n"
+ "var string = ndb.returnString(1);\n"
+ "return JSON.parse(string);\n" + "}\n"
+ "SysU.returnString = function returnStringJS(){\n"
+ "var string = ndb.returnString(1);\n"
+ "print('String returned by the java function SysU.returnString() '+string);\n"
+ "return string;\n" + "};\n"
+ "print('====================Using the same engine instance for execution====================');\n"
+ "(function (){" + "var json = {};\n"
+ "print(\"String Returned in Caller SysU.returnString(): \"+SysU.returnString());\n"
+ "print(\"Object Returned in Caller SysU.returnObject(): \"+SysU.returnObject());\n"
+ "print(\"**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): \"+JSON.stringify(SysU.returnObject()));\n"
+ "print('Adding the object in another ( json.ext = SysU.returnObject();) ...');\n"
+ "json.ext = SysU.returnObject();\n"
+ "print(\"Added JSON object which is stringified to display JSON.stringify(json): \"+JSON.stringify(json));\n" + "})();";
try {
engine.eval(source);
Bindings oldEngineBindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Bindings localBindings = engine2.getBindings(ScriptContext.ENGINE_SCOPE);
Bindings newBindings = engine.createBindings();
oldEngineBindings.put("fileName","oldEngine");
localBindings.put("fileName","localEngine");
newBindings.putAll(oldEngineBindings);
newBindings.putAll(localBindings);
oldEngineBindings.putAll(localBindings);
ScriptContext ctxt = new SimpleScriptContext();
ctxt.setBindings(oldEngineBindings, ScriptContext.ENGINE_SCOPE);
engine.setContext(ctxt);
engine.eval(""
+ "print('====================Using the same engine with original binding ====================');\n"
+ "(function (){" + "var json = {};\n"
+ "print(\"String Returned in Caller SysU.returnString(): \"+SysU.returnString());\n"
+ "print(\"Object Returned in Caller SysU.returnObject(): \"+SysU.returnObject());\n"
+ "print(\"**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): \"+JSON.stringify(SysU.returnObject()));\n"
+ "print('Adding the object in another ( json.ext = SysU.returnObject();) ...');\n"
+ "json.ext = SysU.returnObject();\n"
+ "print(\"Added JSON object which is stringified to display JSON.stringify(json): \"+JSON.stringify(json));\n" + "})();");
ctxt.setBindings(newBindings, ScriptContext.ENGINE_SCOPE);
engine.setContext(ctxt);
engine.eval(""
+ "print('====================Using the same engine with copied new binding ====================');\n"
+ "(function (){" + "var json = {};\n"
+ "print(\"String Returned in Caller SysU.returnString(): \"+SysU.returnString());\n"
+ "print(\"Object Returned in Caller SysU.returnObject(): \"+SysU.returnObject());\n"
+ "print(\"**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): \"+JSON.stringify(SysU.returnObject()));\n"
+ "print('Adding the object in another ( json.ext = SysU.returnObject();) ...');\n"
+ "json.ext = SysU.returnObject();\n"
+ "print(\"Added JSON object which is stringified to display JSON.stringify(json): \"+JSON.stringify(json));\n" + "})();",newBindings);
ctxt.setBindings(oldEngineBindings, ScriptContext.ENGINE_SCOPE);
engine2.setContext(ctxt);
engine2.eval(""
+ "print('====================Using a different engine instance with original binding ====================');\n"
+ "(function (){" + "var json = {};\n"
+ "print(\"String Returned in Caller SysU.returnString(): \"+SysU.returnString());\n"
+ "print(\"Object Returned in Caller SysU.returnObject(): \"+SysU.returnObject());\n"
+ "print(\"**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): \"+JSON.stringify(SysU.returnObject()));\n"
+ "print('Adding the object in another ( json.ext = SysU.returnObject();) ...');\n"
+ "json.ext = SysU.returnObject();\n"
+ "print(\"Added JSON object which is stringified to display JSON.stringify(json): \"+JSON.stringify(json));\n" + "})();");
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Is this an accepted behavior? or a bug?. I should be able to copy the binding and use them in a different scope in the same engine or different engine instance and yield the same results.
I am testing on Java8u101
Results when you run the test. ReturnObject() function seems to fail when the bindings or the engine instance change.
Definition in engine instance 1
====================Using the same engine instance for execution====================
String returned by the java function SysU.returnString() [{"name" : "John Doe", "age" : 30}]
String Returned in Caller SysU.returnString(): [{"name" : "John Doe", "age" : 30}]
Object Returned in Caller SysU.returnObject(): [object Object]
**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): [{"name":"John Doe","age":30}]
Adding the object in another ( json.ext = SysU.returnObject();) ...
Added JSON object which is stringified to display JSON.stringify(json): {"ext":[{"name":"John Doe","age":30}]}
====================Using the same engine with original binding ====================
String returned by the java function SysU.returnString() [{"name" : "John Doe", "age" : 30}]
String Returned in Caller SysU.returnString(): [{"name" : "John Doe", "age" : 30}]
Object Returned in Caller SysU.returnObject(): [object Object]
**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): [{"name":"John Doe","age":30}]
Adding the object in another ( json.ext = SysU.returnObject();) ...
Added JSON object which is stringified to display JSON.stringify(json): {"ext":[{"name":"John Doe","age":30}]}
====================Using the same engine with copied new binding ====================
String returned by the java function SysU.returnString() [{"name" : "John Doe", "age" : 30}]
String Returned in Caller SysU.returnString(): [{"name" : "John Doe", "age" : 30}]
Object Returned in Caller SysU.returnObject(): [object Object]
**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): undefined
Adding the object in another ( json.ext = SysU.returnObject();) ...
Added JSON object which is stringified to display JSON.stringify(json): {}
====================Using a different engine instance with original binding ====================
String returned by the java function SysU.returnString() [{"name" : "John Doe", "age" : 30}]
String Returned in Caller SysU.returnString(): [{"name" : "John Doe", "age" : 30}]
Object Returned in Caller SysU.returnObject(): [object Object]
**Stringified Object Returned in Caller JSON.stringify(SysU.returnObject()): undefined
Adding the object in another ( json.ext = SysU.returnObject();) ...
Added JSON object which is stringified to display JSON.stringify(json): {}
EDIT :-
Found this thread https://bugs.openjdk.java.net/browse/JDK-8067642 . This mentions something about foreign objects being instances of ScriptObjectMirror . I used the typeof operator to display the type of object returned in the cases that failed and succeeded and both times they were ScriptObjectMirror but the stringify works as expected if i use the original bindings object in the context.
EDIT 2:-
Added a very simple test to demonstrate the above. Kinda like a TLDR for the above :) . Executing the below demonstrates that putAll() on a bindings object does not work as we expect it to.
#Test
public void testParsingObjects() throws ScriptException {
String source = "var Func = {};\n"
+ "Func.getJavaScriptObject = function(){"
+ "var jsString = '{\"foo\":\"bar\"}';\n"
+ "return JSON.parse(jsString);"
+ "};";
String executor = "(function(){ "
+ "var obj = Func.getJavaScriptObject();"
+ "print(JSON.stringify(obj));"
+ " })();";
System.out.println("Executing source...");
engine.eval(source);
System.out.println("\nUsing the same binding instance and engine\n");
engine.eval(executor);
Bindings originalBinding = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Bindings copiedBinding = engine.createBindings();
copiedBinding.putAll(originalBinding);
System.out.println("\nUsing the copied binding instance and engine\n");
engine.eval(executor,copiedBinding);
}
Result of execution.
Executing source...
Using the same binding instance and engine
{"foo":"bar"}
Using the copied binding instance and engine
undefined
Here is the code I am using the share compiled JavaScript code between ScriptContext instances used by different threads. The main benefit here is only compiling the code once, although I also benefit from not needing to stream the code from the REST API multiple times. I did not include the REST part for brevity.
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.ArrayList;
import java.util.List;
public class ContextDemo {
static CompiledScript codeLib;
static ScriptEngine engine;
static ScriptContext context;
static List <Future<String>> taskResults;
static ExecutorService executor;
static List <Callable<String>> tasks = new ArrayList<Callable<String>> ();
public static void main(String[] args) {
try {
// Initialize workers and execute
run(4);
} catch(InterruptedException | ExecutionException | ScriptException e) {
System.out.println(e.getMessage());
}
}
static void run(int workers) throws InterruptedException, ExecutionException, ScriptException {
// Initialize engine and initial context
engine = new ScriptEngineManager().getEngineByName("nashorn");
context = new SimpleScriptContext();
engine.setContext(context);
// Compile a JavaScript object with a function
codeLib = ((javax.script.Compilable)engine).compile("var lib = { func1: function(n, s) { return 'thread number ' + n + ': ' + s; } };");
// Create executor with specified number of workers
executor = Executors.newFixedThreadPool((int)workers);
for (int i = 0; i < workers; i++) {
tasks.add(workerLambda(i));
}
// Invoke worker pool
taskResults = executor.invokeAll(tasks);
// Iterate futures list and report results
for (int i = 0; i < workers; i++) {
Future < String > f = taskResults.get(i);
if (f.isDone()) {
System.out.println(f.get());
} else {
System.out.println("Thread " + i + " not done");
}
}
// Shutdown the executor
executor.shutdown();
}
static Callable <String> workerLambda(int n) {
int workerNum = n;
// Thread-specific script context initialization
SimpleScriptContext threadContext = new SimpleScriptContext();
threadContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
try {
// Inject compiled code library into thread-specific ScriptContext
codeLib.eval(threadContext);
} catch (ScriptException e1) {
System.out.println(e1.getMessage());
}
// Return the lambda
return () -> {
// Call the injected object method and return the result
return (String)engine.eval("lib.func1(" + workerNum + ", 'Hello!');", threadContext);
};
}
}
This outputs:
thread number 0: Hello!
thread number 1: Hello!
thread number 2: Hello!
thread number 3: Hello!
I wish I could provide a working solution to this, but I am suspecting it may be a Nashorn bug. As evidence, I submit this link to an old JDK bug:
https://bugs.openjdk.java.net/browse/JDK-8023363
Test.java (below) is provided in the link as evidence that both issues (lack of key presence in Map and inability to execute function after .putAll() into new Bindings) are "Not an Issue". Except that I tested the same code and got different results:
The original Bindings only seems to contain the key "nashorn.global", even after the eval
Attempts to execute "func(x)" using the new Bindings (after putAll()) throws a Reference error
Test.java follows:
import javax.script.*;
import java.util.Map;
public class Test {
public static void main(String[] args) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine scriptEngine = m.getEngineByName("nashorn");
Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
scriptEngine.eval("function func(x) { print('I am func ' + x); }");
// print stuff exposed in engineBindings
for (Map.Entry<?,?> entry : engineBindings.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Bindings localBindings = scriptEngine.createBindings();
// copy all exposed from other bindings
localBindings.putAll(engineBindings);
// put additional variable
localBindings.put("event", new Object());
scriptEngine.setBindings(localBindings, ScriptContext.ENGINE_SCOPE);
scriptEngine.eval("func(event)");
}
}

pass multiple arguments __doPostBack

Is it possible to pass multiple arguments in the __doPostBack call?
I Know how I use one arrgument
__doPostBack('Service', $("input[name=celservice]:checked").val());
and in code behind vb.net
If eventTarget = "Service" Then
'Something
EndIf
but how when I use two arguments
We have created our own library to pass data from web page to ASP.NET. Without getting too much into details, the javascript code wraps info into an XML stream (you can use JSON just as well) that is then parsed on the server.
At its core, our javascript object looks something like this:
function MyArgs() {
var args = '';
this.add = function (id, value) {
args += ('<param id="' + encodeURI(id) + '" value="' + encodeURI(value) + '" />');
};
this.output = function () {
return '<request>' + args + '</request>';
};
}
And we use it like this:
var args = new MyArgs();
args.add("param1", "value A");
args.add("param2", "Value B");
__doPostBack("YOUR_SERVICE", args.output());
We like it because we are quite comfortable with XML data, but you may as well use JSON or URL encoding. The logic is the same: you create a stream that you can parse on the server.
This technique is also useful the other way around, server to client, especially as a response to AJAX requests.
I hope this may be of help to you :)
You can wrap your multiple results in an object, like so:
var result = {
celservice: $("input[name=celservice]:checked").val(),
somethingElse: true
}
then
__doPostBack('Service', result);

Passing parameter to json_callback function

I am using an inverse geolocation method from mapquest that looks something like this
function fieldVia_changed(a)
{
if (document.getElementsByName("via"+a)[0].value.trim().length!=0)
{
var via = document.getElementsByName("via"+a)[0].value ;
var strV = via.replace(/ |,/g, "+");
var s = document.createElement('script');
s.src = 'http://open.mapquestapi.com/nominatim/v1/search?q='+strV+'&json_callback=cbv&format=json&polygon=1&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
}
}
The results of the request are processed in the function cbv which accepts a parameter
function cbv(json)
{
v_lat[0] = json[0].lat;
v_lng[0] = json[0].lon;
}
However i need to be able to pass another parameter to the cbv function from fieldVia_changed function so that i can process the information properly. The cbv function definition would look like this function cbv(json,a). I looked all over but i can not find a solution. Is it possible ?
The server side won't usually have the option of passing additional arguments in a JSONP system. A possible solution is to use the value of a in the callback function name, and dynamically create the function as a kind of man in the middle between the cbv() function, allowing you to pass a as a second argument.
function fieldVia_changed(a) {
if (document.getElementsByName("via" + a)[0].value.trim().length != 0) {
// dynamically create the function
window['cbv_' + a] = function (json) {
cbv(json, a);
};
var via = document.getElementsByName("via" + a)[0].value;
var strV = via.replace(/ |,/g, "+");
var s = document.createElement('script');
// call the function cbv_x
s.src = 'http://open.mapquestapi.com/nominatim/v1/search?q=' + strV + '&json_callback=cbv_' + a + '&format=json&polygon=1&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
}
}
function cbv(json, a) {
v_lat[0] = json[0].lat;
v_lng[0] = json[0].lon;
console.log(a);
}
This is OK if a is some sort of short identifier, if it's from user input then it's not really suitable for use in the function name. You're using in the name attributes so I'm assume this is fine.

Categories

Resources