Oh I see !!
@Jens
Yes but I thought  it was just a convenient way to define the formatter for 
both cases at the same time:

   - single value slider 
   - range slider

[image: Screenshot 2025-10-27 at 09.37.57.png]

But since in my code, *Slider* and *RangeSlider* are 2 different classes, I 
thought I could be more specific and define only the appropriate formatter 
for each case.
But @Colin is right! Even in the case of a *Range* slider, sometime the 
library calls the formatter function with a *single* value (I have no idea 
why, it does not make sense to me but anyway).

So I've change my FormatterCallback as follow (thanks @Colin)
@JsFunction
@FunctionalInterface
public interface FormatterCallback {

/**
* Returns the formatted tool-tip text to be displayed.
*
* @param value the slider value
* @return the formatted tool-tip text to be displayed.
*/
String formatTooltip(Any value);
}

and define then like that :
formatterExample.setFormatter(any -> {
  if (any instanceof JsNumber) {
    return "Current value: " + any.asDouble();
  }
  return null;
});

rangeFormatterExample.setFormatter(any -> {
  if (any instanceof Range) {
    Range range = (Range) any;
    return "Range: [" + range.getMinValue() + ", " + range.getMaxValue() + 
"]";
  }
  return null;
});
Le samedi 25 octobre 2025 à 22:30:46 UTC+8, Jens a écrit :

> The default formatter in bootstrap-slider looks like
>
> formatter: function(val) {
> if (Array.isArray(val)) {
> return val[0] + " : " + val[1];
> } else {
> return val;
> }
> }
>
> IMHO a strong indication that you must use Any or Object and the formatter 
> then needs to check how to format the input. Only if you can guarantee that 
> the component will always call the function with an array you can use a 
> <Range> generic.
>
> -- J.
>
> Colin Alworth schrieb am Freitag, 24. Oktober 2025 um 17:06:40 UTC+2:
>
>> Switching to manual testing in your pom lets me run the test in a real 
>> browser, with breakpoints enabled.
>> diff --git a/pom.xml b/pom.xml
>> index 39c43269..58bd6671 100644
>> --- a/pom.xml
>> +++ b/pom.xml
>> @@ -108,6 +108,10 @@
>>            <inherited>true</inherited>
>>            <configuration>
>>              <sourceLevel>1.8</sourceLevel>
>> +            <testArgs>
>> +              <arg>-runStyle</arg>
>> +              <arg>Manual:1</arg>
>> +            </testArgs>
>>            </configuration>
>>          </plugin>
>>        </plugins>
>>
>> The emulated stack trace experience isn't very much fun, but after a time 
>> it is possible to see that the function is being called with an array, [5, 
>> 10] from inside bootstrap itself - but the bootstrap code specifically 
>> shows that it is only passing the 0th element, as this._state.value[0]. 
>>
>> In order to call the Java lambda with its generic arg, GWT inserts a 
>> typecheck for generics. Range is declared as "actually this is an Array", 
>> so GWT emulates that check with Array.isArray:
>>     Zz(($B = (ZB[b] = iD + oD,
>>     a) == null || (ZB[b] = iD + pD,
>>     Array).isArray(($B = (ZB[b] = iD + oD,
>>     a),
>> Again, this is nasty to read because of emulated stack traces - but 5 
>> clearly fails that check.
>>
>> I then added a `debugger` statement to the JSNI function, to see if it 
>> saw the same thing - it was actually called several times, first with 5, 
>> then 10, before finally the expected [1,2] array. When it received 5 and 
>> 10, the result returned was the useless string "Range: 
>> [undefined,undefined]".
>>
>> Is it wrong for GWT to check the types here? It is causing you a headache 
>> for sure, but the lambda is clearly nonsense if you get a number instead of 
>> a range array. You could take something like Any or Object as the param and 
>> typecheck it, or maybe there's a different way to use bootstrap here to get 
>> the result you expect?
>>
>>
>>
>> On Wednesday, October 22, 2025 at 3:39:28 AM UTC-5 [email protected] 
>> wrote:
>>
>>> Hello,
>>> I'm working on updating/migrating the gwtbootstrap3 library
>>>
>>>    - updating all external Javascript libraries
>>>    - migrating to JsInterop (get rid of jsni)
>>>    - migrating to Bootstrap 5
>>>
>>> But I'm facing an issue with the following @JsFunction
>>>
>>> import jsinterop.annotations.JsFunction;
>>>
>>> @JsFunction
>>> @FunctionalInterface
>>> public interface FormatterCallback<T> {
>>> String formatTooltip(T value);
>>> }
>>>
>>> When I declare it with lambda it fails
>>> // using @JsFunction
>>> slider.setFormatter(range -> "Range: [" + range.getAt(0) + "," + 
>>> range.getAt(1) + "]");
>>>
>>> But if I declare it with JSNI it works
>>> slider.setFormatter(rangeFormatter());
>>>
>>> private native FormatterCallback<Range> rangeFormatter() /*-{
>>> return function (value) {
>>> return "Range: [" + value[0] + "," + value[1] + "]";
>>> };
>>> }-*/;
>>>
>>> You can find the successful and the failing GWTTestCase here:
>>>
>>> https://github.com/freddyboucher/gwtbootstrap3/blob/master/gwtbootstrap3-extras/src/test/java/org/gwtbootstrap3/extras/slider/client/ui/RangeSliderTest.java
>>>  
>>> <http://RangeSliderTest.java>
>>>
>>> And of course the full projet 
>>> https://github.com/freddyboucher/gwtbootstrap3.git
>>>
>>> When I log in the console the 2 functions it looks like that
>>>
>>> ===JSNI===
>>> ƒ (value_0_g$){
>>>     return 'Range: [' + value_0_g$[0] + ', ' + value_0_g$[1] + ']';
>>>   }
>>>
>>> ===JsFunction===
>>> ƒ (){
>>>     return samMethod_0_g$.apply(lambda_0_g$, arguments);
>>>   }
>>>
>>> Any idea how to resolve it?
>>> thanks
>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/google-web-toolkit/65394e97-3b9a-4edb-a578-6872c6fa0d25n%40googlegroups.com.

Reply via email to