JSNI script fails, but script succeeds when ran in Chrome Devtools console

I am workin on utilizing an external javascript library called cytoscape.js through JSNI using test data. When I run the script how I want to through JSNI in my java class, it fails to produce the graph. However, when I run it through the Chrome Devtools console, it works correctly.

All of the values pass to the cytoscape.js library seemingly correctly. Currently, the JSNI code fails a test performed by the Javascript library that the console code is able to pass.

Here is the JSNI code I am using:

public static native void cytoscape() /*-{
        var cy = $wnd.cy = $wnd.cytoscape({container: $wnd.document.getElementById('cy'),
            elements: $wnd.glyElements, 
            style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, 
                { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ],
            layout: { name: 'grid', rows: 1 } });

The “$wnd.” is used to get the correct scope.

Here is the console code:

var cy = window.cy = cytoscape({ 
            container: document.getElementById('cy'),
            elements: glyElements, 
            style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ], 
            layout: { name: 'grid', rows: 1 } 

The elements I am using in both cases are stored in a .js file and I have made sure they are accessible in both cases. Like I mentioned, Devtools debug shows me the correct values are passed into the cytoscape.js library.

The JSNI code fails this return statement in the cytoscape.js library:

var plainObject = function plainObject(obj) {
    return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;

If I comment out “&& obj.constructor === Object;” on line 145 of cytoscape.js, the code runs correctly with my JSNI script. This leads me to believe the cytoscape object is being created differently through JSNI than the console. Still, Dev tools lists the console and JSNI method as providing identical objects. How can I update my JSNI code to make it compliant with this check?

Ideally, JSNI should be usable in this case. I am not sure why passing the values in through JSNI causes this if statement to fail when running it through console passes the if statement.

Leave a Reply

1 Comment threads
0 Thread replies
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
newest oldest most voted
Notify of

The problem is that Object isn’t quite the same as Object, and checking instanceof almost certainly does a lot more than cytoscape’s author thinks it does – isn’t JS grand? The cytoscape.js project’s instanceof Object test is not just a test for “is this thing a plain Object rather than an instance of some other type”, but actually tests “is this thing an instance of the Object class in my window instance, and not from any other iframe/window”. GWT’s default linker evaluates your code in an iframe to prevent accidentally leaking global variables and confusing JS loaded into the same… Read more »