How to specify function parameter in class - dart

How do I do something like this (getNames)?
class APIServer {
String name;
Future<String> getNames(String query);
APIServer({this.name, this.function});
}

You need to use the Function type to declare a function variable.
class APIServer {
String name;
Future<String> Function(String query) getNames;
APIServer({this.name, this.getNames});
}
Alternatively, create a typedef signature to tie the function signature to a data type:
typedef NameGetter = Future<String> Function(String query);
class APIServer {
String name;
NameGetter getNames;
APIServer({this.name, this.getNames});
}

Related

Dart object as a value

I remember that Dart objects have a method which does an object return a value by default without pointing to an property. Example:
class A {
final String name;
A(this.name);
...
}
main() {
var obj = A('chesu');
print(obj + ' locuaz');
}
Output: chesu locuaz
But I don't remember that method or decorator and it is not toString().
Use interpolation to compose strings and values. It will automatically call toString method of value.
class A {
A(this.name);
final String name;
#override
toString() => name;
}
main() {
var obj = A('chesu');
print('$obj locuaz');
}
I finally found what I was looking for, it's called callable classes.

Error when using argument matcher in mocking methods in dart null safety

I am getting the following error message when using argument matcher, any, when mocking a method in dart tests using mockito in a null safe dart code base.
What steps need to be taken to fix this issue
error:
The argument type 'Null' can't be assigned to the parameter type 'int'.
Test code can be found here:
class MockNumberTriviaRepository extends Mock implements NumberTriviaRespository {}
void main() {
late GetConcreteNumberTrivia usecase;
late MockNumberTriviaRepository mockNumberTriviaRepository;
setUp(() {
mockNumberTriviaRepository = MockNumberTriviaRepository();
usecase = GetConcreteNumberTrivia(mockNumberTriviaRepository);
});
const tNumber = 1;
const tNumberTrivia = NumberTrivia(number: tNumber, text: "test");
test('should get trivia for the number from repository', () async {
//arrange
when(mockNumberTriviaRepository.getConcreteNumberTrivia(any)).thenAnswer((_) async => const Right(tNumberTrivia));
//act
final result = await usecase.execute(tNumber);
//assert
// UseCase should simply return whatever was returned from the Repository
expect(result, const Right(tNumberTrivia));
// Verify that the method has been called on the Repository
verify(mockNumberTriviaRepository.getConcreteNumberTrivia(tNumber));
verifyNoMoreInteractions(mockNumberTriviaRepository);
});
}
Implementation code can be found here:
abstract class NumberTriviaRespository {
Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(int number);
Future<Either<Failure, NumberTrivia>> getRandomNumberTrivia();
}
abstract class Failure extends Equatable {
const Failure([List properties = const <dynamic>[]]);
}
class GetConcreteNumberTrivia {
final NumberTriviaRespository respository;
const GetConcreteNumberTrivia(this.respository);
Future<Either<Failure, NumberTrivia>> execute(int number) async {
return await respository.getConcreteNumberTrivia(number);
}
}
class NumberTrivia extends Equatable {
final String text;
final int number;
const NumberTrivia({required this.text, required this.number});
#override
List<Object?> get props => [text, number];
}
Mockito has issues with Dart Null-safety. Please see https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md.
You can override the implementation of your mock class to support a null argument by following the recipes on the link above:
class MockNumberTriviaRepository extends Mock
implements NumberTriviaRespository {
#override
Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(int? number) =>
super.noSuchMethod(Invocation.method(#getConcreteNumberTrivia, [number]),
returnValue: Future.value(
Right<Failure, NumberTrivia>(NumberTrivia(text: "", number: 1))));
}

The argumet type ' ' can't be assign to the parameter tyepe List <>

I am trying to get a list of students from the function seasonalStudents and use it in another function studentListener
I want to use unHapyyStd but in this line unHappyStd = [StaticStudents(std.id, null, TotalStudents(std.id, null))]; I get an error The argument type TotalStudents can't be assigned to the parameter Type List<TotalStudents> , How do I fix it ?
class Toppers {
String id;
double passmark;
double failmark;
Toppers(this.id, this.passmark, this.failmark);
}
class TotalStudents {
final String id;
final Image markerIcon;
TotalStudents(
this.id,
this.markerIcon,
);
}
class StaticStudents {
final String id;
final String call;
final List<TotalStudents> totalStds;
StaticStudents(this.id, this.call, this.totalStds);
}
class Students {}
class NearPassedStudents {
String id;
double passmark;
double failmark;
NearPassedStudents(this.id, this.passmark, this.failmark);
}
class GeoStudents {
static List<NearPassedStudents> passedStudentsList = [];
}
void seasonalStudents() {
for (NearPassedStudents std in GeoStudents.passedStudentsList) {
print("student: ${std.id}");
print("student: ${std.passmark}");
print("student: ${std.failmark}");
unHappyStd = [StaticStudents(std.id, null, TotalStudents(std.id, std.passmark))];
}
Future<void> studentListener()async{
////some method
/// use it here
case studentX:
seasonalStudents();
}
}
Your problem is that the third argument in the StaticStudents constructor expects the type List<TotalStudents> but you are sending a TotalStudents object as argument:
StaticStudents(std.id, null, TotalStudents(std.id, null))
Instead, make it a List with the following if you just want a list with a single TotalStudents to be used:
StaticStudents(std.id, null, [TotalStudents(std.id, null)])
As your 3rd argument require list instead of just obj. inside your loop you can do like this
var list = <TotalStudents>[];
list.add(TotalStudents(std.id, null));
unHappyStd = [StaticStudents(std.id, null, list)];

Why there is a colon symbol (:) with the class constructor in Dart?

I am new in Dart(OOP Languange) which it is a bit similar in Java
But this code get me confusion
What is the purpose of colon(:) before the super keyword within SchoolID class that has been inherit with Person class?
Here is the code:
class Person {
String name;
int age;
int height;
Person({this.name, this.age, this.height});
}
class SchoolID extends Person {
int id;
int year;
String name;
SchoolID({this.id, this.year, this.name}) : super(name: name);
}
Another Example ,,, focus on colon the fishmap
AllFish.fromJson(Map<String, dynamic> json)
: fishMap = json.map(
(String k, dynamic v) => MapEntry(
k,
Fish.fromJson(v),
),
);
It's considered as an initializer list which runs before the constructor body, here you're calling the super that means the constructor of your Person class.
It's an initializer. This means the initializer is executed before the constructor body

Initialize class with asynchronous variable

How can I initialize a class with asynchronous variables so that they are set before the class is used? I have my class currently just calling an async init function but I would have to call that separately to wait for it to finish:
class Storage {
String imageDirectory;
String jsonDirectory;
SharedPreferences instance;
String uuid;
init() async {
imageDirectory = '${(await getApplicationDocumentsDirectory()).path}/image_cache/';
jsonDirectory = '${(await getApplicationDocumentsDirectory()).path}/json_cache/';
instance = await SharedPreferences.getInstance();
uuid = instance.getString("UUID");
}
}
Is there a better way to do this?
You might hope that you could have async factory constructors, but they aren't allowed.
So one solution is a static getInstance(), for example:
class Storage {
static Future<Storage> getInstance() async {
String docsFolder = (await getApplicationDocumentsDirectory()).path;
return new Storage(
docsFolder + '/image_cache/',
docsFolder + '/json_cache/',
(await SharedPreferences.getInstance()).getString('UUID'));
}
String imageDirectory;
String jsonDirectory;
String uuid;
Storage(this.imageDirectory, this.jsonDirectory, this.uuid);
}
You could pass parameters into getInstance and thus into the constructor, as required. Call the above with:
Storage s = await Storage.getInstance();

Resources