Dart needs to expose functions callbacks in Futures? - dart

I got a strong background in C# and Javascript and there is nothing I am not getting on Dart with Futures :
Say I got a Future like this :
scoreFile.exists().then((r) => {
if (r){
List<ScoreRow> previousScores = await scoreFile.readAsString();
scores = jsonDecode(previousScores);
}
});
I know this is not allowed because I need to make my callback a foo() function. But why clutter the space with a code to be used only in this place ? I mean, I really need to create as many little functions as I have callbacks ?
I wouldn't do so with really complex processing, (which would be untestable if not put in a proper function) but for such a simple process ?
Or maybe Dart design is "there is no such thing as simple code not to be tested"
Because from a syntaxical point of view, my function already exists, she is just anonymous : she is stored in braces :)
Thank you for your insight :)

I'm not entirely sure what the problem is here.
Your code mixes async and non-async code, which is usually something to avoid unless absolutely necessary (which it rarely is).
You could perhaps write the code as:
if (await scoreFile.exists()) {
scores = jsonDecode(await scoreFile.readAsString());
}
or you could continue doing what you are doing (fixing syntax and type issues):
scoreFile.exists().then((r) async {
if (r) {
var previousScores = await scoreFile.readAsString();
return jsonDecode(previousScores);
}
}).then((scores) {
// use the scores variable.
});
If you use the then approach, then yes, you will have to make a lot of little callbacks because that's how it works. If you use the async/await syntax, those callbacks will be made for you.

Related

Looking for a better way in Dart to manage an error

So I have added code into a Dart Application that runs a check to see if a response is authorized and I have set it up so there is a simple 3 line bit of code that is needed in the method to check. I'm worried though that if I am not the one programming it how can we ensure that those lines get added. The code looks like below
#Operation.get()
Future<Response> returnGroupFromRegistrationCode(
#Bind.query('code') String code,
) async {
final result = await getRegistrationCodeGroupResult(context, code);
final unauthorizedResponse = result.unauthorizedResponse;
if (unauthorizedResponse != null) {
return unauthorizedResponse;
}
The final unathorizedResponse are the 3 lines that need to be added. The logical way is to add this check in the getRegistrationCodeGroupResult but I can't return the method early without a null check. Is there an error I could throw if and API is being used correctly because I didn't see an applicable one on the list? Just looking for potential ways to improve the code and make it easier to use in the future, any ideas welcome!
A few things I could hope for.
an error that could work to be thrown if the API is being used incorrectly
a way to cut off a function early without the null check
a way to possible integrate a standard into Lint or some autoformat or a scripted way to check if the lines of code are included

Does it make sence using final keyword whenever it possible?

А piece of code where in my opinion the final keyword is redundantly, is not it?
Are there any real advantages of using final in cases like this?
#action
void markAllAsCompleted() {
for (final todo in todos) {
todo.done = true;
}
}
No semantic advantage. People differ on the readability advantage.
Some people think it's an advantage that you can see that a variable won't ever change.
It's being explicit about something which would otherwise be implicit in the code.
Others think that it's unnecessary detail and verbosity that doesn't pay for itself. Sometimes adding more information, if that information isn't really needed, is just adding more noise.
It's effectively a trade-off between explicitness and verbosity which is likely to tip in different direction for different uses. For example, a larger scope for the variable might make it more impactful to declare the variable as final up-front, because it cues you to the variable not changing before reading a lengthy method. In a short method, like this one, you can see immediately that there are no assignments to todo, and reading final up front just slows you down ... unless you are so used to reading final everywhere that it doesn't really rise to the level of conscious thought.
It's individual.
Given that you cannot omit the keyword, it's in no way redundant.
void markAllAsCompleted() {
for (final todo in todos) {
todo.done = true;
}
}
The alternative would be
void markAllAsCompleted() {
for (var todo in todos) {
todo.done = true;
}
}
So there is nothing redundant here. It's a choice, you can either use var or final or the datatype. Of those, only the datatype would be really redundant. So of the choice between final or var I see no reason to use the one that applies to your situation.
So if it can be final, why not make it final.

How to Determine in Dart when a method is Overridden?

I've got a method that does the default approach when an error occurs and simply dumps the error to the user's computer screen:
void onError(FlutterErrorDetails details) => FlutterError.dumpErrorToConsole(details);
Now, the user is invited to override this method, of course, but when the time comes and an error does occur, I want to know if the method was overridden or not. I can't figure out how one would do this however.
In Dart, functions are first-class objects, and so is there not a way to 'record' what the method was as the class defines it, and what it is now when the class object is instantiated? Something like:
static final FlutterExceptionHandler _dumpError = (FlutterErrorDetails details) => FlutterError.dumpErrorToConsole(details);
if (onError == _dumpError) {
_prevOnError(details);
} else {
onError(details);
}
Now the above doesn't work, of course. onError does not equal _dumpError. I even tried this:
static final FlutterExceptionHandler _dumpError = FlutterError.dumpErrorToConsole(details);
void onError(FlutterErrorDetails details) => _dumpError;
Now this actually works in that, when an error occurs, onError() fires and dumps the error to the console. However, it's not quite right as the comparison (==) would, again, return false. How do I make it true?: onError == _dumpError
Is there a way to do this, you think? Is there a way to compare the 'contents' of two functions??
I dunno. I'm grasping at straws at this point.
Cheers.
"I want to know if the method was overridden or not. I can't figure out how one would do this however". The point of OOP is that you shouldn't ever need to care, or even know, if that had happened. What's your actual use case?

Add a property to an object (or at least similar outcome)

First, the context of what I'm doing. I am running an HttpServer which is handling HttpRequests.
HttpServer.bind(ADDRESS, PORT).then((HttpServer server) {
listenSubscription = server.listen(onRequest);
});
void onRequest(HttpRequest request) {
//handle request here
}
I'd like to add some logging to all this, and due to the asynchronous nature of it all, want to add some identifying marker to the requests (so I can match up the request receipts with the responses, fer example). The code inside of onRequest() calls a bunch of other functions to do different things (handle GET vs POST requests, etc.), so simply generating an id at the top is a cumbersome solution as I'd have to pass it around through all those other function calls. I am, however, already passing around the HttpRequest object, so I thought it would be nice to throw an id field on it, just like you would in Javascript, except that Dart doesn't work that way.
Thoughts then went to subclassing the HttpRequest class, but converting the HttpRequest object the onRequest() method receives seemed like much more trouble and overhead than my needs required.
So I ask, is there any idiomatic Dart way attach some data to an existing object? If there isn't something idiomatic, what is the simplest (both in code and runtime complexity) way you can think of to accomplish this?
Well, there's an Expando, but I don't know the performance implications.
Something like:
// somewhere top level. Create this once.
final loggingId = new Expando();
...
// inside of onRequest
loggingId[request] = generateId();
...
// later inside log()
print(loggingId[request]);
Expandos are like weak-reference maps, from my understanding.

Getting multiple references to the same method = multiple objects?

I'm new to Dart, so maybe I'm missing something here:
This works:
In my main(), I have this:
var a = _someFunction;
var b = _someFunction;
print("${a == b}"); // true. correct!
Where _someFunction is another top-level function.
This does NOT work: (at least not how I'm expecting it to)
Given this class...
class Dummy {
void start() {
var a = _onEvent;
var b = _onEvent;
print(a == b); // false. ???????
}
void _onEvent() {
}
}
Instantiating it from main() and calling its start() method results in false. Apparently a new instance of some function or closure object is created and returned whenever my code obtains a reference to _onEvent.
Is this intentional behaviour?
I would expect that obtaining multiple references to the same method of the same instance returns the same object each time. Perhaps this is intended for some reason. If so; what reason? Or is this a bug/oversight/limitation of VM perhaps?
Thanks for any insights!
Currently, the behaviour seems to be intentional, but the following defect is open since May 2012: https://code.google.com/p/dart/issues/detail?id=144
If I were to guess, I'd say that setting "var a = _onEvent;" creates a bound method, which is some sort of object that contains both the function as well as this. You are asking for bound methods to be canonicalized. However, that would require the team to create a map of them, which could lead to worries about memory leaks.
I think they made "var a = _someFunction;" work early on because they needed static functions to be constants so that they could be assigned to consts. This was so that they could write things like:
const logger = someStaticLoggingFunction;
This was in the days before statics were lazily evaluated.
In any case, I would say that comparing closures for equality is a edge case for most languages. Take all of the above with a grain of salt. It's just my best guess based on my knowledge of the system. As far as I can tell, the language spec doesn't say anything about this.
Actually, now that I've read (https://code.google.com/p/dart/issues/detail?id=144), the discussion is actually pretty good. What I wrote above roughly matches it.

Resources