Access Javascript Array in C++/Plugin? - javascript

I have written a NPAPI Plugin using firebreath framework. I am able to pass simple numeric values from Javascript and access them in my (C++)plugin, perform operations and then return the result. I would like to know how to operate on vectors now i.e arrays. I do not want to allocate new array inside my plugin and copy the array from JavaScript(Although I have no clue on how to do it). How can I directly access the JavaScript array in my plugin ? Is there a special way to do it ?

From the Firebreath website:
Javascript objects can be used with the FB::JSObjectPtr type. Examples of JavaScript objects that you may want to use include:
Javascript objects (with methods and/or value members)
Javascript Arrays (that you plan to modify; otherwise you can use a container type)
Javascript methods for callback
Arrays are objects; get values with getProperty(n) or getProperty("length") etc
You can also use methods like ->invoke("push", FB::variant_list_of(val)) etc
(on the JSAPI method in order to use the JSObjectPtr type you should use a method that looks something like:)
void doSomethingWithAnArray(const FB::JSObjectPtr& array) { ... }
Also remember that FireBreath can't tell what type of js object it is, just that there is a js object; you'll have to do your own error detection for the case where they don't give you an actual array but some other object instead.

Related

KnockoutJS: ko.mapping.toJS, but do NOT ignore computed properties

In KnockoutJS, we can go
ko.mapping.toJS(object)
and get our object returned with observables and whatnot converted to vanilla Javascript object. Now, ko.mapping.toJS ignores computed properties. I have a scenario where I basically would like the functionality of ko.mapping.toJS to retain my pureComputed fields with whatever value they had at the time.
I've looked into the documentations page, but it looks like the "mapping options" are for the fromJS method, not toJS.
Any way I can convert my Knockout Object to a JS object but retain the pureComputeds being regular properties in the output?
I switched from ko.mapping.toJS to ko.toJS and the output of ko.toJS does include the computed properties like I want, so that seems to be all I need.

JavaScript object key in an x length array

I wasnt quite sure what to call this question but here is what i want to do:
I am currently creating a series geneator for chartjs that will help me create my datasets.
now the way i want to do it is by simply using object keys to extract data from each element in my array.
Each element of an array could look something like this:
as you can see this object contains other objects inside of them.
This creates a problem because say i want the name of the object feedback_skill i would have to do the following:
data.forEach(function (x) {
x['feedback_skill']['name']
});
Which cannot be hold into one variable.
Now what i could do is pass the following array: serieKey = ['feedback','name'] suggesting that the first element in the array is the first key and the next element is the variable i want to hit.
However these datasets can have an unlimited number of layers so my question to you guys is:
Is there a smart way of doing this?
I'm not aware of a native JavaScript way of doing this, but various JavaScript frameworks allow you to access deep-properties from objects like this. For example Dojo has lang.getObject and I can see that there is a JQuery plugin that does something similar, lodash as well. If you're not using these frameworks, then you could always create your own util function to perform something similar.
These types of utility function allow you to pass the target as a "dot-notation" property, so you could call:
lang.getObject("feedback_skill.name", false, x)
Using Dojo for example, but they're all much of a muchness.
I don't see any problem with your approach, unlimited number of layers can be handled in the following manner :
data.forEach(function(x){
for(i in seriesKey)
x = x[seriesKey[i]]; // x will contain whatever you wanted to retrieve when the loop ends
doSomething(x);
}
seriesKey can be an array like the one in your example, with as many elements as you need to traverse to the depth you want.

Keeping insertion order in Angular

I have a HTML fragment that iterates over key, value collection. When I create an object and put some value in, then iterate trough that object via HTML fragment, all works perfectly.
However since I need keys in specific order, I'm using a Map instead of plain object. This time when I debug I can see that my insertion order was preserved, but for some reason the HTML fragment which iterates over collection doesn't seem to know how to do so. I see nothing on my screen when I use the map object, opposed to the regular object when I see unordered content
tr ng-repeat="(key, value) in rowTitlesValues"
Is how my HTML fragment looks like, when I switch rowTitlesValues back to object works again, what am I doing wrong, and how does one keep insertion order or how do I sort object so it's keys are in custom order?
From Angular reference on ng-repeat (link):
Iterating over object properties
It is possible to get ngRepeat to iterate over the properties of an object using the following syntax:
<div ng-repeat="(key, value) in myObj"> ... </div>
You need to be aware that the JavaScript specification does not define the order of keys returned for an object. (To mitigate this in Angular 1.3 the ngRepeat directive used to sort the keys alphabetically.)
Version 1.4 removed the alphabetic sorting. We now rely on the order returned by the browser when running for key in myObj. It seems that browsers generally follow the strategy of providing keys in the order in which they were defined, [...]
If this is not desired, the recommended workaround is to convert your object into an array that is sorted into the order that you prefer before providing it to ngRepeat. You could do this with a filter such as toArrayFilter or implement a $watch on the object yourself.
Additionally, I do not think Angular 1.x knows how to iterate over a Map. I believe this line in the code proves it:
collectionKeys = [];
for (var itemKey in collection) { // iterates your object using `in`, not `of` or `Map.forEach()`
...
}
// ng-repeat then iterates the collectionKeys to create the DOM
So you will probably need to act as Angular docs suggest:
[...] convert your object into an array that is sorted into the order that you prefer before providing it to ngRepeat. You could do this with a filter such as toArrayFilter or implement a $watch on the object yourself.

How is $('h1') logging to the web console as an array in jQuery?

If you do console.log($('some selector')) in the browser, it returns what looks like an array (first line):
But notice that it's not an instanceof Array, but it's actually the jQuery object.
When you do console.dir($('h1')), it shows it's actually the jQuery object.
The question is, how are they making it look like it's an array in the web console? I noticed in the jQuery source here they add reference to a few Array and Object methods, and here they add toArray (and slice and others) to the jQuery object. Is the web console somehow checking for these methods and if it finds one (toArray, indexOf, slice, etc.), it prints it as an Array? I would like to get this behavior out of any custom object, such as the Ember.ArrayProxy. Currently when you log the Ember.ArrayProxy it shows > Object or whatever, but it would be nice to show it as an array.
Any ideas?
You make your object inherit Array using the prototype, like so:
function SomeType() {
this.push(16);
}
SomeType.prototype = [];
SomeType.prototype.constructor = SomeType; // Make sure there are no unexpected results
console.log(new SomeType()); // Displays in console as [16]
And, of course, all jQuery objects are instances of the jQuery function/constructor, so that's how jQuery does it. As a bonus, because of the inheritance, you get all the methods from Array, and the indexing that comes with it too!

How to convert the result of jQuery .find() function to an array?

What does jQuery .find() method return? a object OR a array list of objects?
If it returns an object which contain all the matched elements. How to convert this object to an array?
If it returns a array of elements, why $(xml).find("DATE").sort(mySortFunc); does not work, it seems the jQuery .find() returns an object which can not apply Javascript sort() method which is supposed to be applied on array.
Generally, I need to sort the objects find by $(xml).find("DATE") , but when I use sort function, it raised an error that the object can not be resolved.
The majority of jQuery methods returns a jQuery object, which can be accessed like it is an array (e.g. it has a .length attribute, elements can be accessed using the square bracket notation ([0]), and it supports some array methods (slice())).
jQuery has a method called toArray() which can be used to convert the jQuery object to a real array.
You can also use get() with no arguments to achieve the same effect (and save you a few key presses).
In future, you can checkout the jQuery API, and the return type for all jQuery methods is listed in the relevant documentation (e.g. for find(), the return type is "jQuery")
If you call .get() on a jQuery object without a parameter, it will return a regular array of DOM elements.
jQuery already acts like an array, and thus you can apply array like functionality to it.
Try to change
$(xml).find("DATE").sort(mySortFunc);
with
Array.prototype.sort.apply($(xml).find("DATE"), mySortFunc);
and you should get what you need

Categories