Dart: Future<void>.then(_) requires callback with parameter - flutter

I feel like I'm probably way overthinking this... but I was working with the Flutter Camera module and wrote the following code:
controller = CameraController(camera, ResolutionPreset.medium, enableAudio: false);
controller.initialize().then((_) {});
However... This confused me, as controller.initialize() returns a Future, and the .then() requires a parameter of type void. I attempted writing the .then Future without a parameter, and I got a compilation error.
So my question is: why does the callback on completion of the Future<void> need to have a parameter at all, if the result is an empty type?
Thanks for any insight!

Actually that's because of the signature of the then method.
The then method signature looks like:
Future<R> then<R>(FutureOr<R> onValue(T value), {Function onError});
As you can see the then is expecting a callback function onValue as an argument.
The onValue callback indeed takes one argument and returns a FutureOr ( FutureOr<R> is actually a type union of R and Future, meaning the return value can either be of type R or Future).
The analysis server, analysing the code will actually expect the onValue callback to match the specified type regardless of it's argument type being a void.
Hope that helps!

Related

Flutter compute(): Can it be used with only one argument?

From what I'm understanding, compute() takes two arguments: the function name and a variable/argument.
However, is it possible to just run a function straight off?
I have a somewhat heavy task (parsing a JSON blob) that I want to put into a separate thread so it doesn't slow down my UI:
Future<void> fetchData({ref}) async {
....
}
It is currently being used as part of a riverpod ChangeNotifier
await ref.read(myProvider('myId')).fetchData(ref:ref);
However, now in attempting to place it in a compute:
await compute(ref.read(myProvider('myId')).fetchData,_______);
What would I place in the ______ ? I tried, null but that doesn't work. In fact nothing seems to work and the IDE is unhappy because of:
The argument type 'Future<void>' can't be assigned to the parameter type 'FutureOr<dynamic> Function(Null)'.

Fluter : How is whenCompleted() different from then() in Future?

Can somebody please explain How is whenCompleted() different from then() in Future with example?
Based on my understanding:
WhenCompleted:
This is called before then (Immediately the future completes). You can use this function if you do not need the value returned by the future, but you have to do something after the future is completed. It can also return an error.
Then:
You can use this if you need to access the value of the future and do something after the future function is executed. It can aslo return an error.
These are the only differences I could point out.

RxDart BehaviorSubject confusion

I have been using RxDart along my Flutter projects for a while. However I find it confusing that defining a BehaviorSubject you can listen directly to the subject, and also to the subject's stream. I wasn't really able to point out the difference.
Example:
BehaviorSubject<String> _mySubject = BehaviorSubject();
_mySubject.listen((value) => { print('Logging $value'} );
_mySubject.stream.listen((value) => { print('Logging $value'} );
Furthermore, BehaviorSubjects seem to offer two ways to access the last emitted value, from the docs I see the value getter which is synchronous. As well as the last getter returning a Future.
Once again I am confused. If nothing was emitted, then why isn't the value getter returning null? Instead, it just waits. The only workaround I found was to seed the subject with a null value.
Finally, I tried using the last getter as a Future and it never returns. Wether there is data or not. Calling it on the Subject just never seems to work.
EDIT:
Thanks #pskink for pointing out that the stream getter returns the Subject itself, therefore no difference between my two first examples.
value should return null if nothing has been emitted yet, not sure why it didn't work for you. Which version of RxDart are you using?
last on the other hand works a bit different. It will return the last value of a Stream after the Stream has been closed. So you need to call _mySubject.close(); then the Future will be completed (as long as the Stream has emitted any value, otherwise there will be an error).

What is the correct implementation of a callback function?

See two functions below. They lead to the same output [4,6], but are different in set up. Is it correct that only the first function makes use of a callback function? Is the first function preferred(more elegant?) over the other one? And is it correct that 'map' is the higher-order function in the second example as it makes use of the callback function that is within its brackets?
Thanks!
function processArray(arr,callback){
return arr.map(callback)
}
processArray([2,3], function(number){return number*2})
AND
function processArray(arr){
return arr.map(function(element){
return otherFunction(element)})
}
function otherFunction(number){
return number*2}
processArray([2,3])
Is it correct that only the first function makes use of a callback function?
No. arr.map takes a callback. You just don't see its definition here.
Is the first function preferred(more elegant?) over the other one?
Yes, but (probably) not for the reason you think. The anonymous function wrapping otherFunction is pointless. You can also write
function processArray(arr){
return arr.map(otherFunction)
}
function otherFunction(number){
return number*2
}
processArray([2,3])
And is it correct that 'map' is the higher-order function in the second example as it makes use of the callback function that is within its brackets?
In the first example, both processArray and map are higher-order functions. In the second, yes, only map is higher-order.
It's easy to inspect a function to see if it is a higher-order function: is one (or more) of its parameters invoked?

scala method with 2 generics where one can be inferred

I'm new to Scala. I am writing a method which sends a request of type RQ to a server, and receives a response of type Response[RSP]. The simplified version: I define a method to make a call:
def invoke[RQ, RSP](request: RQ): Response[RSP] = {....}
When I invoke the method, all parameters can be inferred if I specify the type of the receiving variable, like this:
val result: Response[Double] = invoke("Hello")
But if I just say invoke("Hello") without assigning it to anything, it won't compile. I have to supply the 2 generic types (e.g invoke[String, Double]("Hello") ). My question is: The String can be inferred from the parameter. Is there a way to write the call specifying only the RSP generic? Something in the lines of : invoke[ , Double]("Hello") ?
No.
This is a feature that has been asked about a number of times. Future versions of Scala may support a syntax similar to named arguments for methods:
invoke[RSP = Double]("Hello")
At the moment, there is nothing much you can do except restructure your code so that the method has only one type parameter, and the second comes from the surrounding context.
The more interesting question is: why do you even care about the return type if you just throw away the result anyway? It looks like your method violates the Command-Query Separation Principle. If your method simply returned Unit, you wouldn't need the second type parameter, and all would work fine. If you actually used the return value, the type inferencer would at least have a chance to infer the second type parameter from the context. But the fact that you have a type parameter for the return value but ignore the return value means that there is no context for the type inferencer to look at.