0
votes

How is it possible to work with int values in jsni methods?

public class Person extends JavaScriptObject{                                                                                                                     

   // some other methods

   public final native void setPoints(int i)/*-{
       this.points= this.points + i;
   }-*/;

   public final native int getPoints()/*-{
        return this.points;
   }-*/;                                                                                    
}

I am using this in a method combined with a JsArray

public static boolean moreThanZeroPoints(JsArray<Person> arr, int index){
     if(arr.get(index).getPoints() > 0){
         return true;
     }
     return false;
}

In arr.get(index).getPoints() gives the following error-message:

    uncaught: Exception caught: Exception: caught: something other than an int was returned from JSNI method.
    package-path:: getPoints(): JS value of type undefined, expected int

For arr.get(index).setPoints(1) i get the same error-message. What is wrong? Please help.

2
What's the class that contains these methods? (a JavaScriptObject subclass I suppose?) What does "doesn't work" mean? (i.e. what does the code that calls these methods look like? what's the expected result? what's the actual result?) - Thomas Broyer
Please add some code of this class. Seeing only this snippet it is very difficult to help you. - qben
i edited my question. hope it helps. - Pero
As far as I see, you have arr.get(index)... without checking if arr has value on that index which leads possibly to some kind of OutOfBoundsException. I corrected your setPoints method's returning type to void because I thought it was just an erratum. If you have copied it right from your code then please revise that. - qben

2 Answers

1
votes

Because points might not exist, you have to coerce undefined into some integer value in getPoints(); either that or add an hasPoints() method and only call getPoints() when points is defined.

// coerce undefined (or null, or 0) to 0
public final native int getPoints() /*-{
  return this.points || 0;
}-*/;

or

// coerce undefined or null to -1
public final native int getPoints() /*-{
  return (this.points != null) ? this.points : -1;
}-*/;

For setPoints(), you had declared a return type of int but never actually returned anything, which is equivalent to returning undefined in JS. qben edited your answer and fixed it by changing the return type to void.

0
votes

Note that the code did not reference the JavaScript window object directly inside the method. When accessing the browser's window and document objects from JSNI, you must reference them as $wnd and $doc, respectively. Your compiled script runs in a nested frame, and $wnd and $doc are automatically initialized to correctly refer to the host page's window and document.

public final native int setPoints(int i)/-{ 
    $wnd.points=  $wnd.points + i;
 }-/;

And should like below:

public final native int getPoints()/*-{
    return  eval('$wnd.' + points);;

}-*/;