Add data to promise return - return

For example:
return getPackages()
.map(function(package){
console.log(package.name);
return latestAsync(package.name)
})
.each(function(version) {
//I want package to make it so it will be in this scope too
console.log(package.name, package.version, version)
});
I want to send package forward to the next each/then at the time the promise is fulfilled.
How is that possible?
I am using bluebird.

You can return a composite value with it, using Promise.props:
return getPackages()
.map(function(package){
console.log(package.name);
return Promise.props({version: latestAsync(package.name), package: package });
})
.each(function(r) {
//I want package to make it so it will be in this scope too
console.log(r.package.name, r.package.version, r.version)
});
Alternative solutions are:
Using .bind to set a scope explicitly and relying on indices.
Nest one level and use closure scoping (put a .then on the latestAsync).
Using a similar approach with an array instead of an object with Promise.all.

Related

Dart Generic Function with Subtype function call

I am not sure if this is even possible but here's my setup:
I have basically 2 Maps holding a special identifier to get some objects.
these identifier is like a versioning number, i may have data in version 8 that belongs to meta version 5. But at the same time, Meta versions up to 10 may exist and not every meta version holds information about every data, so here's where the _filter kicks in.
The filter is able to find to any given value the correct object. So far so good.
My question belongs to the following: (last codeline)
how am i able to say "if you have no matching candidate, generate me a default value"
For this purpose, i tried to force a named constructor with a super class for "Data" and "Meta" called "BasicInformation".
But even if i implement this, how do i call something like T.namedConstructor(); ?
class Repo{
Map<int, Data> mapData;
Map<int, Meta> mapMeta;
Data getData(int value)
{
return _filter<Data>(mapData, value);
}
Meta getMeta(int value)
{
return _filter<Data>(mapMeta, value);
}
T _filter<T extends BasicInformation>(Map<int, T>, int value)
{
//fancy filtering technique
//....
//speudo code
if (found) return map[found]; //speudo code
else return T.generateDefault();
}
}
I've found the following stackoverflow entry: Calling method on generic type Dart
which says, this is not possible without adding a function call.

How do I correctly implement dart future.catcherror? [duplicate]

I have some code like this:
File("foo.txt").readAsString().catchError((e)=>print(e));
The compiler is complaining
info: The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'.
I can't seem to give it what it wants and can't find a single clear usage example in any of the docs (just a long issue in git about how many ways there are to mis-use this). If I take the docs at face value, I should be able to return a bool, or a future, neither make the analyzer happy.
How do I provide this FutureOr?
The documentation for Future.catchError could be a lot clearer, but the relevant part is:
onError is called with the error and possibly stack trace, and the returned future is completed with the result of this call in exactly the same way as for then's onError.
Cross-referencing to the documentation for Future.then, the relevant portion is:
The onError callback must return a value or future that can be used to complete the returned future, so it must be something assignable to FutureOr<R>.
Since File.readAsString returns a Future<String>, your catchError callback also must return a Future<String>. Examples of doing that:
File("foo.txt").readAsString().catchError((e) {
print(e);
return Future.value('');
});
File("foo.txt").readAsString().catchError((e) async {
print(e);
return '';
});
Logically, this makes sense; because given:
String value = await File("foo.txt").readAsString().catchError(...);
then if readAsString succeeds, value should be assigned a String. If it fails, since you catch the exception without rethrowing it, value still needs to be assigned a String.
Put another way, your code is equivalent to:
Future<String> readFoo() async {
try {
return await File("foo.txt").readAsString();
} catch (e) {
print(e);
}
// Oops, missing return value.
}
In general, I strongly recommend using async/await with try-catch instead of using .catchError, which would avoid this confusion.

The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'

I have some code like this:
File("foo.txt").readAsString().catchError((e)=>print(e));
The compiler is complaining
info: The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'.
I can't seem to give it what it wants and can't find a single clear usage example in any of the docs (just a long issue in git about how many ways there are to mis-use this). If I take the docs at face value, I should be able to return a bool, or a future, neither make the analyzer happy.
How do I provide this FutureOr?
The documentation for Future.catchError could be a lot clearer, but the relevant part is:
onError is called with the error and possibly stack trace, and the returned future is completed with the result of this call in exactly the same way as for then's onError.
Cross-referencing to the documentation for Future.then, the relevant portion is:
The onError callback must return a value or future that can be used to complete the returned future, so it must be something assignable to FutureOr<R>.
Since File.readAsString returns a Future<String>, your catchError callback also must return a Future<String>. Examples of doing that:
File("foo.txt").readAsString().catchError((e) {
print(e);
return Future.value('');
});
File("foo.txt").readAsString().catchError((e) async {
print(e);
return '';
});
Logically, this makes sense; because given:
String value = await File("foo.txt").readAsString().catchError(...);
then if readAsString succeeds, value should be assigned a String. If it fails, since you catch the exception without rethrowing it, value still needs to be assigned a String.
Put another way, your code is equivalent to:
Future<String> readFoo() async {
try {
return await File("foo.txt").readAsString();
} catch (e) {
print(e);
}
// Oops, missing return value.
}
In general, I strongly recommend using async/await with try-catch instead of using .catchError, which would avoid this confusion.

How to return ECMASCRIPT 6 Promise from Breeze

A breeze query returns interface breeze.Promises.IPromise.
It is using kris kowal's Q promises., and it uses a Q.Deferred to return a promise.
Q exposes a ES6 compliant Promise with Q.Promise.
How do I get a ES6 Promise out of a breeze query? I basically am hoping for a slick way to convert a Q.Deferred to a Q.Promise.
function getES6Promise () {
var query = breeze.EntityQuery.from("Table");
// How to return as an ES6 Promise?
return em.executeQuery(query);
}
I believe you will have to configure breeze with a wrapper around the Promise that makes it look like a Q.
Breeze only needs a tiny part of the Q interface: defer, resolve, and reject. defer has a promise property. resolve and reject return promises. The promise can come from any library as long as it sports a suitable then method.
Here is a wrapper I cooked up off the top of my head but have not actually tried:
(function () {
function defer() {
var deferred = {}
deferred.promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
})
return deferred;
}
var Q = {
all: Promise.all,
defer: defer,
resolve: Promise.resolve,
reject: Promise.reject
}
breeze.config.setQ(Q)
})()
FWIW, the breeze.Promises.IPromise interface to which your refer is useless and should be removed from the documentation.
The fact of the matter is that the promise returned by a Breeze operation has the shape and characteristics of whatever promise library you choose and certainly need not adhere to that interface.
Many of the API and documentation examples use fail and fin. Obviously those are not methods of an ES6 promise and wouldn't work. You'd want catch for fail and then(finFn, finFn) for fin(finFn).
Fortunately, internally breeze calls promise.then exclusively and makes no use of these other promise methods.
Try my wrapper suggestion sometime and let us know how it works out.

Do something after attribute value got assigned

I would like to do some mapping after the members have been set by angular dart:
#Component(
selector: 'travel-step',
templateUrl: 'packages/TravelPlanner/travelstep/travel_step_component.html',
useShadowDom: false,
publishAs: 'cmp')
class TravelStepComponent {
// Deprecated but impossible to replace, since the new syntax is not ready
#NgTwoWay('step')
TravelStep step;
TravelStepComponent() {
// step is null at the moment
}
}
I'm using angular v. 0.12. When the constructor is called, step is still null.
I could do it with a watch expression but I only want to do it once, so this workaround is not how I want to do it.
You can implement AttachAware and put your code into the attach() method.
Similar behavior can be achieved by implementing ShadowRootAware and onShadowRoot().
You need to give Angular some time to evaluate the bindings and assign the values. Use one of these methods according to your requirements.
Sometimes it might help to (additionally) wrap your code into a
new Future(() {
your code here
});
to delay the execution of your code.
Another approach is to implement a setter and execute your logic there
#NgTwoWay('step')
TravelStep _step;
TravelStep get step => _step;
set step(TravelStep s) {
// your code here
_step = s;
// or here
}

Resources