I have a classmodel in dart with a json mapper like
class DA_Field {
final String strGROUP;
DA_Field({
required this.strGROUP, });
static DA_Field fromJson(json) => DA_Field(
strGROUP: json['GROUP'] as String, );
}
and I want to set a attribute of the attribute strGROUP via a function - so that I can call that sub-attribute 'width' for example by:
intWidth = DA_Field.strGROUP.width
My first attempt was to create a setter - but after a lot of google, I only get in touch to create a setter for the whole modelclass, not for all of the single attributes.
The values should be calculated by a function outside of the class - I thought maybe this could be possible by .forEach function - like ?
DA_Field.forEach((k,v) => k.width = functionxx(k));
But i get following errors:
error: The setter 'width' isn't defined for the type 'DA_Field'. (undefined_setter...)
error: The argument type 'void Function(DA_Field, dynamic)' can't be assigned to the parameter type 'void Function(DA_Field)'. (argument_type_not_assignable)
Can anyone give me a suggestion on how to do that?
Thanks..
Related
I have a freezed data class with some fields. A getter method returns nested elements of one attribute for easier access.
#freezed
class Airport with _$Airport {
const Airport._();
const factory Airport({
required String identifier
required String type,
required List<Runway> runways,
}) = _Airport;
List<Ils> get allIls => runways
.map((runway) => runway.allIls)
.expand((ils) => ils)
.toList();
}
I use the Airport class inside a test where the getter allIls is called. I don't want to fill runways with legit data, instead I directly want to stub the getter method allIls and have it return a list of objects.
What I tried:
Mock the Airport class:
class MockAirport extends Mock implements Airport {}
My test:
test('',
() async {
final airport = MockAirport();
final ilsList = [ils1, il2];
when(airport.allIls).thenReturn(ilsList);
expect(...);
});
However, this gives me the following error:
type 'Null' is not a subtype of type 'List<Ils>'MockAirport.allIls
I have also tried a "normal" method instead of a getter, with the same results:
List<Ils> allIls2() => runways
.map((runway) => runway.allIls)
.expand((ils) => ils)
.toList();
...
when(airport.allIls2.call()).thenReturn(ilsList);
Any idea what I could do?
It looks like you missed a step in setting up your Mocks.
You need to add the GenerateMocks or GenerateNiceMocks attribute somewhere in your library to auto-generate your Airport mocks. I like to have the attribute in the same file as my test, though that can lead to repeated mocks throughout your test files. After you have the attribute, you generate the mock using build_runner.
Lastly, in your second example with the "normal" method, you don't need to add the .call() to your when statement. In fact, adding that will cause the call to fail. It should instead just be when(airport.allIls2()).thenReturn(ilsList).
Here I have defined a method definition with optional named parameter.
class PostBuilder extends StatefulWidget {
final Future<List<Submission>> Function({String? next}) postFetcher;
...
...
}
I can able to invoke that function as expected like below.
class _PostBuilderState extends State<PostBuilder> {
...
...
_fetch() async {
var posts = await widget.postFetcher();
// or
var posts = await widget.postFetcher(next: _items.getLast()?.name);
}
But unfortunately, I cannot figure our how to use it properly and don't know the correct syntax.
PostBuilder((next) => getPosts(next))
This is syntax error that is being thrown by the compiler
error: The argument type 'Future<List<Submission>> Function(dynamic)' can't be assigned to the parameter type 'Future<List<Submission>> Function({String? next})'. (argument_type_not_assignable)
postFetcher takes a named parameter. If you want to assign an anonymous function to it, that anonymous function also must take a named parameter. The syntax for anonymous functions is the same as for named functions (the types for anonymous functions are usually omitted because they can be inferred). You therefore want:
PostBuilder(({next}) => getPosts(next))
I have the next problem when i intend get the data of a messageLogin but because this is a Instance dont be avaliable, but in the watch is avaliable to see the data. The question is how i can to access to this data for storage in a variable?
pst: the images show the content of a messageLogin
Future handleSub(BuildContext context) async {
final Either<LoginMessageModel, JwtMessage> messageLogin =
await blocLogin.handleSubmit();
final msg = messageLogin.value.data[0].messages[0].message;
// final rta = messageLogin.fold((_l) => messageLogin, (r) => null);
print(messageLogin);
// showToast(context, messageLogin.value.jwt);
}
the error that give flutter is that:
The getter 'value' isn't defined for the type 'Either<LoginMessageModel, JwtMessage>'.
Try importing the library that defines 'value', correcting the name to the name of an existing getter, or defining a getter or field named 'value'.
Image of vscode
Variable messageLogin
Code that extract the data
Variable messageLogin
That’s because the interface (or base class) Either<T,K> doesn’t have the value property but a concrete has it instead.
Based on your screenshots I can see that it is an instance of LoginMessageModel so you have two solutions:
Move the value to the base class having in mind that all the inherited will access that property;
Cast the object (messageLogin as LoginMessageModel).value... so you can get rid of the warning and explicitly assume the type there;
How to convert 'List' to 'Future<List>'. I need get two type ('List' & 'Future<List>' ) in different places
My api response
var data = jsonDecode(r.body);
custList.add(new Customer(
data[i]['CustomerID'],
'${data[i]['ProfileImageUrl']}' + '${data[i]['ProfileImage']}',
'${data[i]['CompanyName']}',
data[i]['Email'],
data[i]['RegisterNumber'],
data[i]['PhoneNumber'],
data[i]['BillingStreet'],
data[i]['BillingCity'],
data[i]['BillingZip'],
data[i]['MasterCountryName'],
data[i]['MasterStateName'],
data[i]['Type'],
new customeraddress(data[i]['BillingStreet'],
data[i]['BillingCity'], data[i]['BillingZip']),
status,
data[i]['CustomerTaxExemptType'],
data[i]['MasterCountryID'],
data[i]['MasterStateID'],
));
How to convert 'List' to 'Future<List>'.
If you are not entirely sure if you get a T or a Future<T>, you can use the FutureOr<T> (documentation) class.
To create a Future<T> from a value to satisfy some compiler syntax, you can use the named constructor Future.value (documentation).
For more information on Futures: What is a Future and how do I use it?
I am working on a mobile application using Flutter 1.7.8.
I collected data from the server in a form of a nested json object, e.g.
class Obj {
final String obj_to_access;
const Obj({this.obj_to_access});
factory Obj.fromJson(Map<String, dynamic> json) {
return Obj(
obj_to_access: json['item']
);
}
some_obj =
{
"id": some_id,
"nested_obj": Obj.fromJson(json["obj_to_access"])
}
However, I can't seem to access the nested Obj with '[]' and it always give me this error: The operator '[]' isn't defined for the class 'Obj'. Try defining the operator.
I saw that I should try defining the '[]' but I am not sure how. Please help thanks
The reason for the error is that you're passing a dynamic value to Obj.fromJson() instead of a Map - which it expects. To solve this issue, you can add cast as <Map<String, dynamic>> to the value to let the compiler know that it's a Map.