I want to invoke a JavaScript function from Java, passing to the function an Object. What I hoped to do is something like:
JSObject obj = new JSObject();
obj.setString("property1", "value);
obj.setNumber("property2", number);
and pass the object to the JavaScript function via the JSFunction.invoke() method. But JSObject apparently has no default constructor, nor methods like "setString". Ditto for JSONString.
I ended up using the Google GSon library to build a JSON string that I then passed to "new JSONString()". Do you have any better way?
I wish your documentation addressed this point instead of forcing me to invent this solution. Not what I wanted to spend time on.
Here is a code sample that demonstrates how to create an object and set some properties to it:
Browser browser = new Browser();
browser.executeJavaScript("function foo(object) { console.log(object.property1); }");
JSObject object = browser.executeJavaScriptAndReturnValue("new Object()").asObject();
object.setProperty("property1", "value 1");
object.setProperty("property2", 15);
JSFunction function = browser.executeJavaScriptAndReturnValue("window.foo")
.asFunction();
function.invoke(null, object);
Related
hi does anyone encountered this error? everytime I use PXSelect on a foreach loop in which on the other source code does but on my code does not, could anyone identify the cause? the code below is also the the original source code from Acumatica but I only changed the Datamember from PaymentCharges to OtherCharges
[PXOverride]
public void VoidCheckProc(ARPayment doc)
{
foreach (PXResult<ARPaymentChargeTran> paycharge in PXSelect<ARPaymentChargeTran, Where<ARPaymentChargeTran.docType, Equal<Required<ARPayment.docType>>, And<ARPaymentChargeTran.refNbr, Equal<Required<ARPayment.refNbr>>>>>.
Select(this, doc.DocType, doc.RefNbr))
{
ARPaymentChargeTran charge = PXCache<ARPaymentChargeTran>.CreateCopy((ARPaymentChargeTran)paycharge);
charge.DocType = Document.Current.DocType;
charge.CuryTranAmt = -1 * charge.CuryTranAmt;
charge.Released = false;
charge.CuryInfoID = Document.Current.CuryInfoID;
charge.CashTranID = null;
//PaymentCharges.Insert(charge);
OtherCharges.Insert(charge);
}
}
I believe, you are writing this method in an extension for the base BLC
So instead of using 'this', use 'this.Base'
The Select method is non-static, as the error message says, but you call it on the PXSelect<...>-type. You need to have an instance of that type.
Based on Hybridzz answer, I assume you used the wrong overload of the Select-method. Probably your arguments do not have the correct type, so the compiler selects the best fitting overload of the method. In this case, it selects the one accepting only the argument params object[] o, which is non-static. A bit misleasing design of the API you use.
If I create an object property via Object.defineProperty() with a getter/setter method (an accessor descriptor) like:
var myObj = function myObj() {
var myFoo = 'bar';
Object.defineProperty(this, 'foo', {
enumerable: true,
get: function() {
return myFoo;
},
set: function(newValue) {
myFoo = newValue;
}
});
return this;
};
If I do something like var f = new myObj(); console.log(f) in Node, the output is something like:
{ foo: [Getter/Setter] }
console.log(f.foo) gets the proper 'bar' value, but is there a way to indicate that upon logging/inspecting, it should just run the getter and show the value?
First, it's important to understand why this happens. The logging functions don't run getters by design because your getter function could have side effects, whereas the logging function can guarantee that getting the value of a primitive doesn't.
When you pass an object to console.log, it's really just passing it off to the util module's inspect to format into human-readable text. If we look there, we see that the very first thing it does is check the property descriptor, and if the property has a getter, it doesn't run it. We can also see that this behavior is unconditional – there's no option to turn it off.
So to force getters to run, you have two options.
The simplest is to convert your object to a string before handing it off to console.log. Just call JSON.stringify(obj, null, 4), which will produce reasonably human-readable output (but not nearly as nice as util.inspect's). However, you have to take care to ensure that your object doesn't have any circular references and doesn't do something undesired in a toJSON function.
The other option is to implement a inspect function on your object. If util.inspect sees a function called inspect on an object, it will run that function and use its output. Since the output is entirely up to you, it's a much more involved to produce output that looks like what you'd normally get.
I'd probably start by borrowing code from util and stripping out the part about checking for getters.
This behavior is certainly intentional. I know I wouldn't want all the getter functions on an object running whenever I logged that object; that sounds like potential a debugging landmine, where debugging could alter the state of my program.
However, if indeed that is the behavior you want, you can add a new function:
Object.getPrototypeOf(console).logWithGetters = function(obj) {
var output = {};
var propNames = Object.getOwnPropertyNames(obj);
for(var i=0; i<propNames.length; ++i) {
var name = propNames[i];
var prop = Object.getOwnPropertyDescriptor(obj, name);
if(prop.get) {
output[name] = prop.get();
} else {
output[name] = obj[name];
}
}
// set output proto to input proto; does not work in some IE
// this is not necessary, but may sometimes be helpful
output.__proto__ = obj.__proto__;
return output;
}
This allows you to do console.logWithGetters(f) and get the output you want. It searches through an object's properties for getters (checking for the existence of Object.getOwnPropertyDescriptor(obj, propName).get) and runs them. The output for each property is stored in a new object, which is logged.
Note that this is a bit of a hacky implementation, as it doesn't climb the object's prototype chain.
obj.prototype.__proto__ = events.EventEmitter.prototype
I have seen the code above sometimes, and I google about it, they say this line copy all of the EventEmitter properties to the obj. And I also see the code like this:
obj.__proto__ = events.EventEmitter.prototype
So I am wondering if they are the same?
I saw the first usage in this article, in which the author gives the exapmle:
var events = require('events');
function Door(colour) {
this.colour = colour;
events.EventEmitter.call(this);
this.open = function()
{
this.emit('open');
}
}
Door.prototype.__proto__ = events.EventEmitter.prototype;
var frontDoor = new Door('brown');
frontDoor.on('open', function() {
console.log('ring ring ring');
});
frontDoor.open();
And he explains:
This line: Door.prototype.__proto__ = events.EventEmitter.prototype; Copies all of the EventEmitter properties to the Door object.
As to the second way, I saw it in the source of hexo, in the init.js, there are code:
var hexo = global.hexo = {
get base_dir(){return baseDir},
get public_dir(){return baseDir + 'public/'},
get source_dir(){return baseDir + 'source/'},
get theme_dir(){return baseDir + 'themes/' + config.theme + '/'},
get plugin_dir(){return baseDir + 'node_modules/'},
get script_dir(){return baseDir + 'scripts/'},
get scaffold_dir(){return baseDir + 'scaffolds/'},
get core_dir(){return path.dirname(dirname) + '/'},
get lib_dir(){return dirname + '/'},
get version(){return version},
get env(){return env},
get safe(){return safe},
get debug(){return debug},
get config(){return config},
get extend(){return extend},
get render(){return render},
get util(){return util},
get call(){return call},
get i18n(){return i18n.i18n},
get route(){return route},
get db(){return db}
};
hexo.cache = {};
// Inherits EventEmitter
hexo.__proto__ = EventEmitter.prototype;
// Emit "exit" event when process about to exit
process.on('exit', function(){
hexo.emit('exit');
});
The statements are not the same.
Rather than obj.prototype.__proto__ = events.EventEmitter.prototype, I'd expect to see something like Constructor.prototype.__proto__ = events.EventEmitter.prototype, (where Constructor is any kind of constructor function, so could have any name. They're often capitalized.) because the prototype property is typically only available on functions, and does not have any special meaning when defined as a property of a regular (non-function) object.
In other words, obj in first line of code given should be a (constructor) function to make sense, and it's very uncommon to see a function have such a generic variable name as obj.
If you'd share the source where you find the exact first statement, this may clear things up.
The second example is the simplest. There's no constructor involved. hexo is a plain object created with an object-literal. The author wants the EventEmitter methods to be available through the hexo method, so he assigns EventEmitter.prototype to the __proto__ property, which actually changes the prototype of hexo.
The first code example is somewhat more complex. Here the author wants to ensure that any objects that are constructed by the Door function will provide access to the EventEmitter methods. Any object constructed by the Door function will get Door.prototype as its prototype. This particular prototype now has the EventEmitter as its prototype, so the EventEmitter functions are accessible by going two steps up the prototype chain.
"Copies all of the EventEmitter properties to the Door object." - this particular comment is misleading. No properties are copied. The only that happens is this.
door = new Door
door.on("open", function() { console.log("door has opened")})
The prototype of door is now Door.prototype. If a property (in this case on) is not found when trying to access it, the JS engine will look at this prototype. The prototype of door - Door.prototype - has no on defined either, so the JS Engine will see if Door.prototype has a prototype. It does, in the form of events.EventEmitter.prototype. And this object does have an on property defined.
Hope this makes things somewhat more clear. Javascript prototypical inheritance is quite tricky.
See also Confusion about setting something.prototype.__proto__
The prototype property is generally found on constructors, that is, Functions that create new objects. The prototype of a constructor is the object that is used as the prototype for the newly instantiated object.
The __proto__ property of an object points to the object which was used as a prototype, when the object was first instantiated. It is non-standard, so there's no guarantee that your JavaScript engine will support it.
In your examples, you can see that they refer to Door.prototype and hexo.__proto__. The crucial difference here is that Door is a constructor, whereas hexo is an instance of an object.
However, Door.prototype is an instance of an object, so to get its prototype, you need to use __proto__.
In both instances, the RHS of the assignment is a constructor, so refers to prototype.
In summary, if you want the prototype that will be used by a constructor, use prototype. If you want the prototype of an instantiated object, you may be able to use __proto__.
In truth, you may better off just using Object.getPrototypeOf.
Source
Everything in JavaScript is object. And every object, it may be a function, {}, new Object(), in JavaScript has an internal property called [[Prototype]].
[[Prototype]] is the very reason for prototype inheritance in JavaScript. This internal property is exposed to the programmer through __proto__. This is a non-standard. Not all JS environments support this.
How does an object we create using constructor functions gets its [[Prototype]]?
Only objects whose [[Class]] is Function gets the property prototype. What it means is that every function declared when executed by the JS engine, it creates an object. Its [[Class]] is set to Function and a property prototype is attached to this function object.
By default this prototype is an object with one property constructor pointing to the function object.
When the above function is invoked as part of new operator like new constructorFn(), the JS engine creates an object, its [[Class]] property set to Object and [[Prototype]] property set to the object pointed to by the [[Prototype]] of the constructor function.
Since this new created object is of class Object, it does not have the prototype property.
In nutshell, __proto__ exists in every object. prototype exists, by default, only in objects whose [[Class]] is Function. What this means is only functions (created via function statement, function expression, Function constructor ) will have this property.
I am trying to create a dynamic instance of a class at the runtime by using the system.dynamic. and pass it to the threadpool to execute it. But, I am getting an error saying the method in the class is used as a property. Below is the code.
Type t = Type.GetType("clsCountrySelectInsertUpdate_TEST");
dynamic dd = Activator.CreateInstance(t, null);
dd.intMode = 203;
ThreadPool.QueueUserWorkItem(new WaitCallback(dd.CountrySelectInsertUpdate));
I tried to call the method in the threadpool as below as well, but got an error saying that the return type void cannot be converted from the method CountrySelectInsertUpdate.
ThreadPool.QueueUserWorkItem(new WaitCallback(dd.CountrySelectInsertUpdate()),null);
The method CountrySelectInsertUpdate() does not take a parameter and returns a void.
Any help would be much appericated
WaitCallback requires state. You could easily use a lambda to write this:
ThreadPool.QueueUserWorkItem(new WaitCallback(state => dd.CountrySelectInsertUpdate()), null);
That being said, as you're already using .NET 4, I'd recommend using the TPL instead. It provides a nicer threading model in general than ThreadPool.QueueUserWorkItem, especially if you later need to get the results (or handle exceptions):
Task.Factory.StartNew( () => dd.CountrySelectInsertUpdate());
I'm working with Dust.js and Node/Express. Dust.js documents the context helpers functions, where the helper is embedded in the model data as a function. I am adding such a function in my JSON data model at the server, but the JSON response to the browser doesn't have the function property (i.e. from the below model, prop1 and prop2 are returned but the helper property is not.
/* JSON data */
model: {
prop1: "somestring",
prop2: "someotherstring",
helper: function (chunk, context, bodies) {
/* I help, then return a chunk */
}
/* more JSON data */
I see that JSON.stringify (called from response.json()) is removing the function property. Not sure I can avoid using JSON.stringify so will need an alternative method of sharing this helper function between server/client. There probably is a way to add the helper functions to the dust base on both server and client. That's what I'm looking for. Since the Dust docs are sparse, this is not documented. Also, I can't find any code snippets that demonstrate this.
Thanks for any help.
send your helpers in a separate file - define them in a base context in dust like so:
base = dust.makeBase({foo:function(){ code goes here }})
then everytime you call your templates, do something like this:
dust.render("index", base.push({baz: "bar"}), function(err, out) {
console.log(out);
});
what this basically does is it merges your template's context into base, which is like the 'global' context. don't worry too much about mucking up base if you push too much - everytime you push, base recreates a new context with the context you supplied AND the global context - the helpers and whatever variables you defined when you called makeBase.
hope this helps
If you want stringify to preserve functions you can use the following code.
JSON.stringify(model, function (key, value) {
if (typeof(value) === 'function') {
return value.toString();
} else {
return value;
}
});
This probably doesn't do what you want though. You most likely need to redefine the function on the client or use a technology like nowjs.