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;
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).
Why does this code:
class _SequentialTextPageState {
String jsonTextPref = 'seqtext';
int jsonTextSuff = 10;
String jsonText = jsonTextPref + jsonTextSuff.toString();
}
generate these errors?
Error: The instance member 'jsonTextPref' can't be accessed in an initializer.
Error: The instance member 'jsonTextSuff' can't be accessed in an initializer.
It seems to me that concatenation between String and int is correct?
Dart initializes objects in multiple phases. Initializing members directly ("field initializers") occurs early in object initialization, before this becomes valid, so that phase cannot initialize members that depend on other parts of the object.
Dart provides multiple ways to initialize members, so if one member needs to depend on another, you can initialize it in a later phase by using a different mechanism. For example, you could do one of:
Add the late keyword to make the dependent member lazily initialized.
Move initialization of the dependent member into the constructor body.
In the case of a Flutter State subtype, you could initialize the dependent member in its initState method, which in some cases is more appropriate.
Note that in some cases you additionally can consider replacing the member variable with a read-only getter instead. For example, in your case, perhaps you could use:
String get jsonText => jsonTextPref + jsonTextSuff.toString();
That would be appropriate if jsonText should always depend on jsonTextPref and jsonTextSuff, would never need to have an independent value, and if it's acceptable for jsonText to return a new object every time it's accessed.
Dart does not allow field initializers to refer to the object itself. Fields must always be fully initialized before any access is given to the object begin created.
The initializers can only access static and top-level variables, not any instance variables on the object itself.
With null safety, you will be allowed to write late String jsonText = this.something + this.other;. That field will then not be initialized until it's first read or written, which is necessarily after the object itself has been created.
You can only use constant expressions as initializers. x=this.y is not constant.
The error was displayed when I did following:
class MyClass {
String id;
String[] imagePaths;
}
It will mark the String in the line String id; as error, but the error is in the next line, it should be List<String> imagePaths; instead of String[] imagePaths; then the error in the line above also disappears. This can be very confusing if you have a big class and the actual error is many lines underneath the first marked line (talking from experience...)
I want to build a method to dynamically save attributes on a specific object
given the attribute name and the value to save I call the "save()" function to update the global targetObj
var targetObj = targetClass();
save(String attribute, String value){
targetObj.attribute = value;
print(targetObj.attribute);
}
But I'm getting the following error:
Class 'targetClass' has no instance setter 'attribute='.
Receiver: Instance of 'targetClass'
Tried calling: attribute="Foo"
The only thing that I can think of is that "attribute" due to being type String results in an error.
That lead me to think if there is a way to read a String as code, something like eval for php.
As #Randal mentioned, you cannot create class..method at runtime. Still, you can try something like this.
A certain class
class Foo {
dynamic bar1;
dynamic bar2;
// ...
}
Your save method
save(Foo fooObject, String attribute, dynamic value) {
if ("bar1" == attribute) fooObject.bar1 = value;
else if ("bar2" == attribute) fooObject.bar2 == value;
// ...
}
Dart (and thus flutter) does not have a way to compile and execute code at runtime (other than dart:mirrors, which is deprecated). You can build additional code that derives from other code using the various builder mechanisms, although it can be rather complicated to implement (and use!).
Being introduced to BLoC, I create a simple class that alters the value of a bool variable:
class SignInBloc {
StreamController<bool> _isLoading = StreamController<bool>();
Stream<bool> get getIsLoading => _isLoading.stream;
set setIsLoading(bool isLoading) => _isLoading.sink.add(isLoading); // Here is my problem (set)
void dispose(){
_isLoading.close();
}
}
When I use the set keyword and then call for it in my UI screen: bloc.setIsLoading(false);
I get an exception:
Try correcting the name to the name of an existing method, or defining a method named 'setIsLoading'.
But when I take off the set keyword in my SignInBloc class, it works fine. I am confused, isn't it best to use this keyword rather than directly declaring my setter? and,
Why do I not get an error when I take it off?
Setters are meant to be used as if they were public fields of the class. You're just explicitly defining your own setter. Directly assign your intended value to the setter like so:
bloc.setIsLoading = false;
The only benefit of using set is being able to use this syntax.
When you take off set, it's being changed to a normal method where bloc.setIsLoading(false); would be the correct syntax.
This question already has answers here:
What is the true meaning of pass-by-reference in modern languages like Dart?
(3 answers)
Closed 1 year ago.
In this post: Flutter video_player dispose
I asked how to dispose something so I can re-use it again. The answer provided works correctly but it left me with this question:
why does this code work as intended? eg it disposes the old instance from videoController using oldController
final oldController = videoController;
WidgetsBinding.instance.addPostFrameCallback((_) async {
await oldController.dispose();
_initController(link); //contains reassignment of videoController = VideoController.network(...)
});
in C or similar languages, a use of pointer is needed (or should I say my preferred way). To pass the reference, assign a new value to it and then take care of the old one.
Sorry that my answer left you with a confusion. Yes, in Dart you work with references to objects, just like in Java. I'll give a short example that should make it clear for you why this code works as intended:
void main() {
final t = Test(Test());
t.removeField();
}
class Test {
Test t;
Future<void> removeField() async {
print('current field: $t');
Future.delayed(Duration(seconds: 2)).then((_) => print('delayed value: $t'));
t = null;
}
Test([this.t]);
}
prints:
current field: Instance of 'Test'
delayed value: null
In this case, field's value is set to null first and then 2 seconds later callback executes. It accesses object's field, but it's already null. But if we make it like this:
final old = t;
Future.delayed(Duration(seconds: 2)).then((_) => print('delayed value: $old'));
it prints:
current field: Instance of 'Test'
delayed value: Instance of 'Test'
We stored previous value of the field and passed it to the callback, so it won't access nulled field.
Dart does not support passing by reference. Dart is only passed by value, just like Java. Java also does not support reference passing.
Is Java “pass-by-reference” or “pass-by-value”?
https://stackoverflow.com/a/40523/1737201
Below is a little proof.
void main() {
// The variable "myVar" is a "lvalue" (storage of value)
// Now we assign the value to "myVar" via "rvalue" "Object()"
final myVar = Object();
// Remember the old value
final oldObject = myVar;
// Now we will try to pass by reference.
// We assume that we will pass the reference of storage ("lvalue")
// ("myVar" im our case) because we cannot reference the value (pure data)
// because the value does not contain storage location information.
tryChangeMyVarByRef(myVar);
// Check the result passing by reference
// If storage of value was passed by its reference then changing
// the value in this storage should have effect.
assert(!identical(myVar, oldObject));
// Epic fail because Dart does not support pass by refernce.
print('WOW, it works!');
}
void tryChangeMyVarByRef(Object referencedStorgeOfValue) {
// Try change the value stored in referenced storage of value
referencedStorgeOfValue = Object();
}
EDIT:
The value (or more correct rvalue which means a data whitout any storage) cannot have an address because the value is just a data. In programming impossible to reference the data (because there are no any way to do that) but possible to reference the storage of data (eg. address of variable) because the storage are always has some location rather than data (data only can be stored at some location but not referenced because data can be replaced at any time at this location and thus this cannot be called as reference to data because this can be incorrect after data reassigment would be perfomed but should be only called as reference of some storage of some data).
In the programming the term "pass by reference" means: pass the reference (address of the location) of the value storage (that is, the address of some varibale with any data but not the address of this data).
This allows to replace (but not just change) stored data at some location becuase the storage was referenced (address of laocation was known).
Which means only one thing: you pass reference of the variable where some value are stored.
And this does not means the reference of some value as many newbie wrongly think (who never used C or C++ language).
Another important thing is that the in Dart the object (or instances) itself are references because they are boxed (the values was stored in the heap).
This creates illusion that you pass by reference but at the same time you pass by value the reference (where reference as value is passed by value). Pass by value the reference is not the same as pass by reference the reference.
Free advice to newbie: Learn the C or C++ programming languages to find out the difference between the following things:
Pass by value the reference
Pass by reference the reference
In both cases the value itself is a reference but in first case you pass the value (reference) by value but in second case you pass the value (reference) by reference.
Enjoy!