Specifying optional parameters when calling JavaScript functions in Dart - dart

I'm calling the function window.navigator.geolocation.getCurrentPosition from Dart code. The final parameter to this function is optional. In JavaScript I would set the optional parameters as follows:
var wpid = navigator.geolocation.watchPosition(geo_success, geo_error,
{enableHighAccuracy:true, maximumAge:30000, timeout:27000});
What would the equivalent be in Dart code? I've tried the following but I'm not sure if it is correct:
window.navigator.geolocation.watchPosition(geo_success, geo_error,
{'enableHighAccuracy':true, 'maximumAge':30000, 'timeout':27000});

You are using this method: http://api.dartlang.org/docs/bleeding_edge/dart_html/Geolocation.html#watchPosition
int watchPosition(PositionCallback successCallback, [PositionErrorCallback errorCallback, Object options])
I do not have Dark SDK on this machine, but to me it looks completely fine. If the JavaScript equivalent code is just an object, then passing a Dart Map just like what you have done should be working. Is there a problem with it?

Hopefully passing a Map works, please try and let us know.
Even if it does work, this is a bad Dart API. The options really should be optional parameters, not properties of an options object. I filed a bug here: http://dartbug.com/6280

Related

Deedle, F# and read csv

I am facing an issue when I try to use the function Deedle.Frame.ReadCsv
I am trying to use the overload here: https://collective2.com/c2explorer_help/html/806c0295-1a9f-1bf4-50eb-a221419abe06.htm
let schemaSource = "dateRep (DateTime),,,,,,,,,"
let dataSource = Deedle.Frame.ReadCsv(path = "data.csv", schema = schemaSource)
When I do so, I get the following error:
error FS0503: A member or object constructor 'ReadCsv' taking 0 arguments is not accessible from this code location. All accessible versions of method 'ReadCsv' take 9 arguments.
What I do not get is that all but path are optional. If I use just:
Deedle.Frame.ReadCsv("data.csv")
It then works...
Any idea? I tried to find some resources on using overloaded functions from other .Net languages with optional parameters but I have not been successful.
I am not sure why the Intellisense/Signature shown in Visual Studio was wrong but using location = works...

What is the difference and preferred way between jsonEncode() and json.encode() in Dart?

In Flutter doc, it uses jsonEncode(), while in Angular doc, it uses json.encode(). What is the difference and preferred way between the two?
jsonEncode as alias for json was introduced because json often collided with a varible name json many used for the variable that holds the JSON value.
var json = http.get(...);
var data = json.decode(json); // error
var data = jsonDecode(json); // ok
There is no difference. From the the dart:convert docs for jsonEncode:
Shorthand for json.encode.
In the upcoming Sound Null-Safety update, currently in beta, the alias jsonEncode does not work, so just use json.encode

Fable F# to Javascript: Parameterless functions being given a parameter when referenced

I am having difficulty referring to parameterless functions in Fable.
With this example:
let f1 () =
1
let someRefTof1 = f1
I'd expect the generated js to look something like this:
function f1() {
return 1;
}
var someRefTof1 = f1;
but what I actually get is:
function f1() {
return 1;
}
var someRefTof1 = exports.someRefTof1 = function someRefTof1(arg00_) {
return f1(arg00_);
};
I'm unclear on the purpose of arg00_ or how to avoid it being generated?
(As a bit of background, I am struggling to call a function in an external js library which expects a function to be passed as a parameter)
Edit:
Background
The above is what i believe to be a minimal, verifiable, reproduction of my question but, after comments, I thought it may be useful to provide a touch more context on why this is causing issues. What I am actually trying to do is use angularjs from Fable.
So my example looks more like this:
let app = AngularFable.NgFable.angular.``module``("app",[||])
type TestCtrl() =
member this.Val1() = "boom";
app?controller("test", TestCtrl)
which gets compiled to:
var app = exports.app = angular.module("app", []);
var TestCtrl = exports.TestCtrl = function () {
function TestCtrl() {
_classCallCheck(this, TestCtrl);
}
TestCtrl.prototype.Val1 = function Val1() {
return "boom";
};
return TestCtrl;
}();
_fableCore.Util.setInterfaces(TestCtrl.prototype, [], "App.TestCtrl");
app.controller("test", function (unitVar) {
return new TestCtrl();
});
with unitVar being the problematic parameter introduced in this example. When I use this in my html with something like:
<div ng-app="app">
<div ng-controller="test as vm">
{{vm.Val1()}}
</div>
</div>
I run into an unknown provider error whereas if I simply change the compiled javascript to remove the unitVar parameter from the last line like this:
app.controller("test", function () {
return new TestCtrl();
});
then my example works as expected.
I'd really like to know if there is a way to avoid having the Fable compiler generate this parameter. I'm 99% sure this reduces to the same problem as in my original question but I've included this additional context to better explain why this is an issue
Thank you very much for your question and detailed explanations. There're two things here that are a bit tricky and are caused by optimisations both of the F# compiler and Fable.
In the AST provided by the F# compiler, methods (functions that are members of a type or module) are compiled as usual methods as in C#. This is for optimization.
However, when you create an anonymous lambda or make a reference to a method, the F# compiler will keep F# semantics, that is, all functions have a single argument (as John Palmer says, unit is an argument too) and can be curried.
Ok, this info is just to make clear why the F# compiler/Fable represent methods and lambdas differently. Let's go with the issue of argumentless functions: the obvious solution would be of course to remove the F# compiler generated argument for functions accepting unit (as it's already done for methods). In fact, I also had problems with libraries like Mocha because of this.
I did try to remove the unit argument at the beginning but I got fails in some scenarios because of this. TBH, I don't remember now exactly which tests were failing but because of the expectation that there'll be always an argument, in some cases function composition or inlining was failing when the unit argument was removed.
Other attempts to modify the semantics of F# functions in the JS runtime have always failed because they don't cover all scenarios. However, we can be more lenient with delegates (System.Func<>) as it's usually safe to assume these ones should behave more like functions in languages like C# or F#. I can try to remove the unit argument just for delegates and see what happens :)
For more info about sending F# functions to JS code you can check the documentation.
UPDATE: Scratch all that, please try fable-compiler#0.6.12 and fable-core#0.6.8. This version eliminates unit arguments, the solution was actually simpler than I thought and (hopefully) shouldn't create issues with existing projects. (The explanation about methods and lambdas compiled differently still applies.)

How to define a method for the class 'Proxy' in Dart js-interop?

I'm currently calling a jQuery based plugin called Bootstrap Context Menu.
In order to call it, I need to use the Javascript Interop library. But when I call a jQuery method from it I receive the following warning:
The method 'jQuery' is not defined for the class 'Proxy'
Code snippet:
js.scoped(() {
js.context.jQuery('#canvas').contextmenu();
});
This was not happening before some dart/js-interop updates. What is the right way to get rid of this warning?
You get this warning because the new analyzer doesn't seem to be aware of the option Report 'no such member' warnings when class defines noSuchMethod() ( Reported at http://dartbug.com/10016 ). If you switch back to the legacy analyzer you shouldn't see this warning anymore.
That said if you want to use the new analyzer and get rid of this warning you can use the array notation like this :
js.context["jQuery"]('#canvas')["contextmenu"]();
But :
it's less readable particullary for method calls.
it's less efficient for method calls because 2 operations are done ( f = js.context["jQuery"] followed by f('#canvas') ) instead of 1 ( js.context.jQuery('#canvas') )

Groovy closure short-form method call doesn't work when bound via delegate?

I've created a code sample that shows the issue I'm having:
class BindingExample {
public static void main(String[] args) {
Closure closure1 = {
printit.call("Hello from closure 1")
}
Closure closure2 = {
printit("Hello from closure 2")
}
Closure printit = { s ->
println("printing: "+s)
}
Binding binding = new Binding()
binding.setVariable("printit", printit)
closure1.delegate = binding
closure2.delegate = binding
closure1() //This works fine
closure2() //This does not.
//Why does .call() work and () alone not? Most documentation says they're the same.
}
}
Printit is a Closure, which the documentation indicates implements doCall and therefore is callable in short form via ().
However, when this closure is made available via binding to a delegate, only the long-form version of the call is permitted. The output is:
printing: Hello from closure 1
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: groovy.lang.Binding.printit() is applicable for argument types: (java.lang.String) values: [Hello from closure 2]
Can someone explain why this is the case? If possible, I'd like to also see how to make it so the short-form version works. I was able to make it work by defining printit as a proper static method (not a closure), but that won't work for my case because I actually need printit to be given some data available only inside of the method scope (not included in the example since my question relates to the binding itself).
As to WHY this is the case, I can't give a definite answer, unfortunately. There's some talk about implicit-"this" annotation, etc. It seems like it should work, but that there's some vagueness about what should be tried first (this-scope or delegate).
That the issue exists, currently, seems correct. I've found the following other resources that agree, with some discussion without resolution about why.
Nabble discussion about the issue:
http://groovy.329449.n5.nabble.com/Binding-Closure-property-not-called-as-method-td5562137.html
JIRA ticket resulting:
https://issues.apache.org/jira/browse/GROOVY-5367

Resources