async/await problem when extend super class - flutter

I need to set the order of execution of my methods on the constructor of my supper class because i have a multiple class that extends from this supper class and the order is the same on all of them (take advantage of abstract class), but i am facing a strange problem where i get a result of a variable before the finishing of the future, this is a simulation code of my above description, you can try it on dartpad.dev:
abstract class SuperClass {
bool _success;
bool get isSuccess => _success;
set setSuccess(bool success) => this._success = success;
SuperClass() {
//checkLogin();
runCode();
//sendRequest();
}
runCode() async {
await doSomething();
}
Future<void> doSomething();
}
class SubClass extends SuperClass {
String text;
#override
Future<void> doSomething() async {
text = await Future.delayed(Duration(seconds: 2), () => '2 sec of getting data');
if (text.isNotEmpty) {
setSuccess = true;
print(text);
}
print('value of success is "$isSuccess" from the overriding method');
}
}
void main() async {
SubClass subClass = new SubClass();
// if (subClass.isSuccess) // how can i get success from the sub class
// do somthing else
print('value of success is "${subClass.isSuccess}"');
}
the result is :
value of success is "null"
2 sec of getting data
value of success is "true" from the overriding method
My question is why i get the value of the variable from the super class while i am running the future method before it and read it from the sub class ?
Did i miss something or how i can handle this logic ?

you need another method in the abstract class, when creating an object from the subclass, calling abstract class constructor automatically, you are calling "doSomething" override method in the constructor by "runCode" method, but since "doSomething" method is override method It will be called automatically in subclasses, So you need another method

If your question is about why you get the print in this order rather than:
2 sec of getting data
value of success is "true" from the overriding method
value of success is "true"
that is just because you call the async function runCode() in the constructor of SuperClass which is implicitly called when you create a SubClass as the latter inherits from the former. Since the method is async and you are not awaitint it, the method starts running on a different thread and code execution is not stoped there waiting for the runCode() method to return.
This means that runCode() starts executing in a different thread and immediately after that, the SuperClass constructor returns, the SubClass method (which implicitly called the former) also returns, and then your print statement from main executes. Since these steps take less than two seconds to execute, they finish executing before the rest of runCode()

Instead, you can remove the runCode() from the abstract class constructor and call the doSomething() method after initializing:
void main() async {
SubClass subClass = new SubClass();
await subClass.doSomething();
print('value of success is "${subClass.isSuccess}"');
}

Related

Best way to get value from future in constructor in dart

what ways you suggest for getting value from future in object constructor ?
class F{
late SomeObj<t> _obj;
F(){
() async{
_obj = await someFuture();
}.call();
}
somefunc() => doing something with _obj
}
but this doesn't gave me right res in the right time,
Other ways for this situation?
Here are two possible approaches:
Make your class's constructor private and force callers to instantiate your class via an asynchronous static method. From the perspective of callers, there is little difference between calling a static method and a named constructor.
class F {
late SomeObj<T> _obj;
F._();
static Future<F> create() async {
var f = F._();
f._obj = await someFuture();
return f;
}
Object? someFunc() => doSomethingWith(_obj);
}
Explicitly make everything that depends on the asynchronous value also asynchronous. If _obj is initialized asynchronously, then _obj should be a Future. If someFunc depends on _obj, then someFunc should return a Future.
class F {
Future<SomeObj<T>> _obj;
F() : _obj = someFuture();
Future<Object?> someFunc() async => doSomethingWith(await _obj);
}

How to verify a method inside a method is called in mockito

I was doing some unit testing in flutter with mockito, and I feels unable to verify a method is called within another method. The code I've written so far as follows,
The class I want to test
class A {
void doSomething() {
callMe();
}
void callMe() {}
}
Mocked class
class MockA extends Mock implements A {}
The test I wrote,
test("Test method is called", () {
A a = new MockA();
a.doSomething();
verify(a.callMe()).called(1);
});
When I run the above test I am getting an error
No matching calls. All calls: MockA.doSomething()
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)
If i verify doSomething is called it works, but for a call on callMe within doSomething doesn't work. Is this the default behavior or am I doing something wrong? Please note I need to verify the callMe() method is called when doSomething() is called.
You mocked A and replaced it with MockA. Mocks have no implementation. MockA.doSomething() does nothing and does not and cannot call MockA.callMe().
That A.doSomething() calls A.callMe() should be considered an implementation detail of of doSomething(); making a test rely on that would tightly couple the test to the specific implementation and would be brittle.
You can't use a mock to verify the implementation of the thing being mocked. If you want to verify the implementation of A.doSomething(), you instead should use an actual object and verify observable properties on that object.
But if you still really want to do this, then you would need to modify A to not call methods on itself and to instead call methods on a provided object (i.e., "dependency injection"). For example:
class A {
final late A a;
A({A? a}) {
this.a = a ?? this;
}
void doSomething() {
a.callMe();
}
void callMe() {}
}
test("Test method is called", () {
var mockA = MockA();
var actualA = A(a: mockA);
actualA.doSomething();
verify(mockA.callMe()).called(1);
});
It's a bit unusual for a class to depend on a mock of itself, however, and it would not scale if you then want to verify calls made by callMe().
Another approach that would scale better (but with significantly more work) would be to create your own fake class that tracks method calls:
class TrackedA implements A {
int doSomethingCallCount = 0;
int callMeCallCount = 0;
#override
void doSomething() {
doSomethingCallCount += 1;
super.doSomething();
}
#override
void callMe() {
callMeCallCount += 1;
super.callMe();
}
}
But again, that's very brittle, and I would not recommend it.

How to call a function from a different class

I am trying to call the following hideOverlay function from a separate class
hideOverlay() {
overlayEntry?.remove();
overlayEntry = null;
if (overlayEntry != null) {
overlayEntry.remove();
overlayEntry = null;
}
}
In a separate class, I have imported the file containing the function and attempted to call the file by using.
hideOverlay();
I am a super newbie please advise what I am doing wrong :-(
Put hideOverlay() as a method in a Class, lets call that class 'FirstClass' and from a separate class call an object of the FirstClass class and call that hideOverlay() method like this.
import 'first_class.dart';
class SecondClass {
FirstClass firstClass;
//call function like this when needed.
firstClass.hiveOverlay()
}

Dart/Flutter: Use a 'final' variable, that is loaded asynchronously

I am running into an issue regading using a final variable that is still loaded in asynchronously still after initializing, hence throwing a 'Re-initializing Exception'. The problem is that I am initializing a final instance of class A inside of class B. But the classA's contructor seems to be doing some async work as well. As a result (seems to be the case after debugging), that the required arguments of classA are the only ones initialized when the instance is created. And when the rest of attributes of classA are initialized async, it tries remodifying the instance, throwing an Exception. The skeleton looks like:
class classA {
_mainAttribute;
_otherAttributes . . .;
//getters . . .
classA (this.mainAttribute) {
// async call
_waitForJsonParse().then((_jsonRoot) {
// initialize _otherAttributes;
}
}
Future _waitForJsonParse() async {
return await . . .;
}
}
class classB {
late final List<classA> _errorCausingAttr;
classB () {
// another async call
_loadAssetManifest().then((manifestMap) {
_errorCausingAttr = List.unmodifiable(
mainfestMap.getFolders()
.map((String folderName) => classA(folderName.someValue())
);
// Exception occurs here: "LateInitializationError:
//Field '_errorCausingAttr#33137322' has already been initialized.".
}
}
Future _loadAssetManifest() async {
return await . . .;
}
}
My first solution was to not use 'final' variables then. But is there a way to do it without sacrficing the kind of declaritive schemes? Maybe there is a better pattern / there is a code smell here?

Swift - how to implement protocol methods in function

In android, it is possible to implement interface methods during function call. For example, the declaration of interface and function:
//interface
interface exampleCallback {
void success(String response);
void error(String error);
}
//function
void exampleFunction(exampleCallback cb) {
//do something
}
And the function call:
exampleFunction(new exampleCallback() {
#Override
public void success(String response) {
//custom method implementation
}
#Override
public void error(String error) {
//custom method implementation
}
});
That is, the success/error methods can be customized for each function call of the exampleFunction.
However, after some google search, I can only find example codes for implementing protocol methods in class or struct declaration, in which the methods can no longer be customized. I know I can pass escaping closure as function parameter to achieve the goal, i.e., customize callback function for each function call. But just wonder if I can use protocol to do the similar thing...
You can create an enumeration with associated values:
enum Result {
case success(String)
case error(CustomError)
}
enum CustomError: Error {
case expired(String)
}
And use the enumeration cases in a completion handler of your method to pass your custom string:
func exampleFunction(completion: #escaping (Result) -> ()) {
if condition {
completion(.success("Success String"))
} else {
completion(.error(.expired("Error String")))
}
}
When calling your method you can switch your enumeration and do your custom implementation there as well as use the associated value returned in your callback:
exampleFunction { result in
switch result {
case let .success(response):
// custom method implementation
// use your (response) string here
case let .error(error):
// custom method implementation
// use your (error.localizedDescription) string here
}
}
Playground Sample
Anonymous classes in Java is really just a "workaround" for the absence of functions as "first class citizens".
In swift, functions are first class citizens, so you don't actually need to pass an anonymous class that implements a single method. You just pass that method (somewhat similar to Java 8's lambdas).
This in Java:
interface ActionListener {
void actionPerformed();
}
Can just be represented by a closure type in Swift:
() -> Void
Instead of doing this:
someMethod(new ActionListener() {
public void actionPerformed() { ... }
});
You do this in Swift:
someMethod { ... }
What if your interface in Java has multiple methods to implement?
In that case, you can't use one single closure to represent them all. You need to either
create a protocol with multiple methods and implement it in a struct or class. You see this pattern a lot in UIKit. Views and view controllers often has a XXXDelegate.
pass a tuple of closures