Reputation: 115
Given the following classes:
abstract class ParentState extends Equatable {
const SomeState();
}
class SomeState extends ParentState {
const SomeState({required this.someField});
final String someField;
@override
List<Object> get props => [someField];
}
I want to access someField
if the current state is of type SomeState
in my mapEventToState
method, but the compiler doesn't allow that:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
if (state is SomeState) {
print(state.someField); // Error: The getter 'someField' isn't defined for the type 'ParentState'.
}
}
If I manually create a ParentState
variable, however, it works as expected:
ParentState state = SomeState(someField: 'test');
if (state is SomeState) {
print(state.someField); // Works.
}
Also, manually casting in mapEventToState
works, but that shouldn't be required:
if (state is SomeState) {
print((state as SomeState).someField); // Works.
}
What am I missing?
Upvotes: 0
Views: 90
Reputation: 17123
In your first example with the error, it seems like state
is a field in the surrounding class with an auto-generated getter and setter.
However from the perspective of the analyzer, it's possible for state
to also be a getter function that allows the return of a different object each time the getter is called. So on the first call to the getter in the if
statement the getter could return a SomeState
object, but in the if
body, the getter could return a completely different object without a someField
getter.
To get around this problem, you just need to create a local copy of your variable within the function and use that copy instead of the class field:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
final stateCopy = state;
if (stateCopy is SomeState) {
print(stateCopy.someField);
}
}
Upvotes: 1