0

With Jint how can I set a property (or invoke a method) of an instance of a javascript class?

e.g. if I do:

var o = new Jint.Engine().Evaluate(@"
class MyClass {
  constructor() {
     this.myProperty = null;
  }
}

const o = new MyClass;
return o;
");

how do I then set the myProperty value of the returned o object?

This is using Jint v3.

lycandroid
  • 181
  • 10

1 Answers1

0

To access stuff you got back from Jint, you turn it into an object by calling ToObject() on it and declare it as dynamic so you can use arbitrary properties:

dynamic o = new Jint.Engine().Evaluate(
@"
class MyClass {
  constructor() {
     this.myProperty = null;
  }
}

const o = new MyClass;
return o;
").ToObject();

Console.WriteLine(o?.GetType() ?? "<null>"); //System.Dynamic.ExpandoObject

Console.WriteLine(o?.myProperty ?? "<null>"); //<null>

o.myProperty = "why not this string";
Console.WriteLine(o?.myProperty ?? "<null>"); //why not this string
Console.WriteLine(o?.myProperty?.GetType() ?? "<null>"); //System.String

o.myProperty = 99;
Console.WriteLine(o?.myProperty ?? "<null>"); //99
Console.WriteLine(o?.myProperty?.GetType() ?? "<null>"); //System.Int32

Now AFAIK there is no built-in way to change a property and continue working with it in the Javascript. Two options I can think of:

  1. Declare the class in C# and pass an instance to Jint via SetValue(). Changes to the object instance will be available in Jint.

  2. Hack up something like this to change arbitrary stuff from within Jint:

public static void SetProperty(this Jint.Engine engine, string propertyPath, object value)
{
    string tempname = "super_unique_name_that_will_never_collide_with_anything";
    engine.SetValue(tempname, value);
    engine.Evaluate($@"{propertyPath} = {tempname}; delete globalThis.{tempname};");
}
BenderBoy
  • 346
  • 2
  • 8
  • All that shows is arbitrary properties being set on the .NET side. The values are not actually being set in the javascript engine environment. `string myProperty = js.Evaluate("return o.myProperty").ToString(); Console.WriteLine(myProperty); // null.` – lycandroid Oct 05 '21 at 13:05
  • Hi, sorry, I’m not sure that’s easily possible, but I’ve updated my answer with a dumb extension method. – BenderBoy Oct 05 '21 at 20:34