Passing map as a function parameter

212 views
Skip to first unread message

Viktor Remennik

unread,
Mar 25, 2020, 10:29:25 AM3/25/20
to mozilla-rhino
Hi there,

I am a new user looking for nashorn alternatives. In nashorn I use Map to pass an object as a foo parameter. How can I dynamically construct a JS object and pass it to my foo with Rhino?

Thank you 

Michael Bar-sinai

unread,
Apr 22, 2020, 4:46:38 PM4/22/20
to mozilla-rhino
You can use the Context.javaToJS, like so:

Scriptable programScope = ...

try {
   Context.enter();
   programScope.put(name, programScope, Context.javaToJS(obj, programScope));
} finally {
   Context.exit();

Viktor Remennik

unread,
Apr 23, 2020, 3:48:24 AM4/23/20
to mozilla-rhino
But I need to dynamically create JS object. In Nashorn I could use a Map which automatically will be converted to the JS object, i. e. if I put in map "key1","val1" and "key2","val2", and then put this map to the context, it will be available in JS like
{
   key1: "val1",
   key2: "val2"

Michael Bar-sinai

unread,
Apr 23, 2020, 4:00:55 PM4/23/20
to mozilla-rhino
To dynamically create a JS object, you can use ScriptableObject and put it in the JS program scope. 

Viktor Remennik

unread,
Apr 23, 2020, 4:16:50 PM4/23/20
to mozilla-rhino
I understand that, but do not know how! )

Michael Bar-sinai

unread,
May 4, 2020, 6:08:44 PM5/4/20
to mozilla-rhino
Something along these lines:

Java
-------

final ScriptableObject spMap = new NativeMap();
Map<String,Object> javaMap = Map.of("a",10,"b",20,"c",35,"dee",500, "last","I'm the last key!");
javaMap.forEach( (a,b)->spMap.put(a, spMap, b) );
try {
  Context.enter();
 YOUR_PROGRAM_GLOBAL_SCOPE.put("dynMap", YOUR_PROGRAM_GLOBAL_SCOPE, Context.javaToJS(javaMap, YOUR_PROGRAM_GLOBAL_SCOPE));
} finally {
   Context.exit();
}

Javascript (bp.log.info is a logger, think of it as println() or console.log )
--------------
if ( dynMap ) {
    for ( let d in dynMap ) {
        bp.log.info( d + ": " + dynMap[d] );
    }
}

Result
---------
[BP][Info] b: 20
[BP][Info] c: 35
[BP][Info] dee: 500
[BP][Info] last: I'm the last key!
[BP][Info] a: 10

You can try to remove the call to Context.javaToJS and just place the object in the scope, since it's a native object. Also, there may be better ways of doing this.... but this works.
Reply all
Reply to author
Forward
0 new messages