I have some difficulty to wrap a function that returns a Future.
I have the following code :
class Foo {
Bar data;
}
Future<Foo> getFutureFoo() {...}
I'm would like to create a wrapper that directly returns a Future<Bar>
Future<Bar> getFutureFooBar() {
var foo_future = getFutureFoo();
???
return bar_future;
}
Is there some kind of future transformer like for Streams ?
Future<Bar> getFutureFooBar() async {
Foo foo_future = await getFutureFoo();
//use the foo object to create the Bar object
return bar_future;
}
Related
I have a List<String> of Dart function names. For example, ['func1', 'func2', 'func3']. I want to call each function in the List. How can I go from a String to a Function? The following code does not work, but conceptually it does what I want:
var func1 = Function('func1');
See how it creates a Function from 'func1'.
Edit: I need to deal with Strings because I read the list of functions from a file.
I don't think Dart allows that at the moment (for objects you could use dart:mirrors, but it's currently marked as an unstable library).
An alternative is to use a Map to associate the strings with the functions, as in:
void foo() {
print('foo');
}
void bar() {
print('bar');
}
void main() {
var functions = {
'foo': foo,
'bar': bar
};
// calling foo()
functions['foo']();
// or
var b = functions['bar'];
b();
}
It seems in the 2.0.0-beta.12 build they removed angular2.http from dart in favor of using dart's built in http classes.
However if you were to do something like the following then property is null until the request sets the property.
class Component {
var property;
Component() {
HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
}
}
What we really want is a promise place holder for the property until the promise is resolved and the view is updated. So how do you do it in angular2 with dart?
Or is there a different dart/angular2 idiomatic way to do it?
HttpRequest.getString(...) returns a Future (Promise in JS/TS land) otherwise you wouldn't be able to call .then(...) on the result.
You can either use async / await
class Component {
var property;
Component() async {
await HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
doSomethingAfterRequestReturned();
}
}
nope - you can't use async / await in a constructor.
Alternatives are static methods or an extra call after object creation. Doing extensive work in the constructor is bad practice anyway.
class Component {
Future<Component> createNewInstance() async {
var c = new Component();
await HttpRequest.getString("/path/to/something")
.then((resp) {
c.property = JSON.decode(resp);
});
return c;
}
var property;
}
and use it like
Component.createNewInstance().then((c) => print(c.property));
with an extra call
class Component {
getData() {
return HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
}
var property;
}
and use it like
var c = new Component()
c.getData().then((_) => print(c.property));
So, I looked into mirror and they might be an option, but given their async nature they might be really awkward to use or just not viable in the long run. Since they are currently not supported (just a play-thing) they are not really viable at this time anyway.
Question: Given a series of Strings, eg. [ "Foo", "Bar" ] a base class Application and Widget in library corelib; and a corresponding class for each of the strings FooWidget, BarWidget in library applibrary;, what's currently the most elegant method to get Application to turn the strings into instances of the corresponding classes, that works with dart2js.
Equivalent PHP pseudo-example for clarity,
<?php # example
namespace corelib;
class Widget {
function name() {
return \get_called_class();
}
}
class Application {
static function resolve($name, $library) {
$class = $library.'\\'.$name.'Widget';
return new $class;
}
}
namespace applibrary;
class FooWidget extends \corelib\Widget {
// ...
}
class BarWidget extends \corelib\Widget {
// ...
}
$foowidget = \corelib\Application::resolve('Foo', 'applibrary');
$barwidget = \corelib\Application::resolve('Bar', 'applibrary');
echo "{$foowidget->name()} <br> {$barwidget->name()}";
Output
applibrary\FooWidget
applibrary\BarWidget
If you can validate the list of strings, then the best way for the moment (until mirror support in dart2js becomes better baked), is likely an if statement.
// toy implementation
Widget getWidget(name) {
switch (name) {
case "Foo": return new FooWidget();
case "Bar": return new FooWidget();
default: // handle error
}
}
// elsewhere:
var fooWidget = getWidget("Foo");
var barWidget = getWidget("Bar");
The list of xyzWidget classes will be a finite list (as you can't dynamically link in code at runtime anyway).
Of course, a more elegant implementation is to use mirrors (shown below, for reference, although it doesn't currently fulfil the dar2js criteria)
Future<Widget> getWidget(library, name) {
var completer = new Completer<Widget>();
MirrorSystem ms = currentMirrorSystem();
ClassMirror cm = ms.libraries[library].classes[name];
// instantiate an instance of the class
cm.newInstance(null,[]).then((instance) => completer.complete(instance));
return completer.future;
}
// elsewhere:
getWidget("applibrary","FooWidget").then((Widget widget) {
// do something with widget
});
In Dart, is it possible for a function to have a prototype associated with it?
Example Javascript code:
doStuff.prototype.isDefined = true; //is there anything like Javascript's function prototypes in Dart?
function doStuff(){
console.log("The function doStuff was called!");
}
Is it possible to do the equivalent of this in Dart (i.e., create a list of properties for each function?)
Two things to address here:
First, Dart doesn't have prototypes or prototypal inheritance, and instead uses classical inheritance. Rather than a prototype, objects have a class, and instead of a prototype chain, objects have superclasses.
Second, for your specific case, I think we'd have to see more of what you need to do to figure out the idiomatic way to do it in Dart. It should soon be possible to emulate functions with objects so that you can invoke an object and still have state and other methods associated with it.
See this article for more: http://www.dartlang.org/articles/emulating-functions/
When that capability lands you'll be able to do this:
class DoStuff {
bool isDefined = true;
call() => print("The function doStuff was called!");
}
var doStuff = new DoStuff();
main() => doStuff();
Which works if you have a fixed set of metadata about your function that you need to keep track of. It's slightly different from JavaScript because each instance of the function in Dart will have its own state for isDefined. I'm not sure if it's possible or easy to get multiple instances of the function in JavasScript, but you might need to make isDefined static so that the value is shared across all instances.
Dart does not allow you to add or remove member variables from an instance of a class at runtime. Rewriting your example in Dart it might look something like this:
class doStuff {
bool isDefined;
doStuff() {
isDefined = true;
}
void stuff() {
print('The function stuff was called!');
}
}
main() {
new doStuff().stuff();
}
If you wanted to add a property bag to a class in Dart you would write:
class PropertyObject {
Map<String, Dynamic> properties;
PropertyObject() {
properties = new Map<String, Dynamic>();
}
Dynamic operator[](String K) => properties[K];
void operator[]=(String K, Dynamic V) => properties[K] = V;
}
main() {
PropertyObject bag = new PropertyObject();
bag['foo'] = 'world';
print('Hello ${bag['foo']}');
}
Note that you can't access map properties using the '.' operator.
I don't know how to use binding with closures in Groovy. I wrote a test code and while running it, it said, missing method setBinding on the closure passed as parameter.
void testMeasurement() {
prepareData(someClosure)
}
def someClosure = {
assertEquals("apple", a)
}
void prepareData(testCase) {
def binding = new Binding()
binding.setVariable("a", "apple")
testCase.setBinding(binding)
testCase.call()
}
This works for me with Groovy 1.7.3:
someClosure = {
assert "apple" == a
}
void testMeasurement() {
prepareData(someClosure)
}
void prepareData(testCase) {
def binding = new Binding()
binding.setVariable("a", "apple")
testCase.setBinding(binding)
testCase.call()
}
testMeasurement()
In this script example, the setBinding call is setting a in the scripts binding (as you can see from the Closure documentation, there is no setBinding call). So after the setBinding call, you can call
println a
and it will print out "apple"
So to do this in the class, you can set the delegate for the closure (the closure will revert back to this delegate when a property cannot be found locally) like so:
class TestClass {
void testMeasurement() {
prepareData(someClosure)
}
def someClosure = { ->
assert "apple" == a
}
void prepareData( testCase ) {
def binding = new Binding()
binding.setVariable("a", "apple")
testCase.delegate = binding
testCase.call()
}
}
And it should grab the value fro a from the delegate class (in this case, a binding)
This page here goes through the usage of delegate and the scope of variables in Closures
Indeed, instead of using a Binding object, you should be able to use a simple Map like so:
void prepareData( testCase ) {
testCase.delegate = [ a:'apple' ]
testCase.call()
}
Hope it helps!
This is really strange behaviour: removing the "def" in front of someClosure declaration makes the script work in JDK1.6 Groovy:1.7.3
Update: This was posted in the answer above. My mistake to repeat it.
Update: Why it works? Without a def first line is taken as a property assignment which calls setProperty and makes the variable available in binding, which is resolved later.
a def should have worked as well as per (http://docs.codehaus.org/display/GROOVY/Groovy+Beans)
someClosure = {
assert "apple", a
print "Done"
}
void testMeasurement() {
prepareData(someClosure)
}
void prepareData(testCase) {
def binding = new Binding()
binding.setVariable("a", "apple")
testCase.setBinding(binding)
testCase.call()
}
testMeasurement()
I could reproduce the problem you mention by following code. But i am not sure if this is the correct way to use Binding. GroovyDocs says they are to be used with scripts. Could you point me to documentation which suggests such usage of Binding with Closures.
class TestBinding extends GroovyTestCase {
void testMeasurement() {
prepareData(someClosure)
}
def someClosure = {
assertEquals("apple", a)
}
void prepareData(testCase) {
def binding = new Binding()
binding.setVariable("a", "apple")
//this.setBinding(binding)
testCase.setBinding(binding)
testCase.call()
}
}
This was answered on groovy mailing list:
In a script, def foo will create a local variable, not a property
(private field + getter/setter).
Think of a script a bit like if it's the body of a run() or main() method.
That's where and how you can define local variables.