Using BLoC as state management, I want to check if an event forwarded to another widget belongs to a certain BLoC abstract class. The reason is that I am using a form containing widget for 2 different use cases / BLoCs and depending on the BLoC I need to use a different event. There is also a minor other difference between the use cases which is why I would like to identify the use case by the event passed when calling the widget. Sure, I could also pass a bool with that info, but then thought why not recognizing the abstract class of the event.
So let's assume I have
abstract class EditEvent extends Equatable {
const EditEvent();
}
class EditItemDeselected extends EditEvent {
EditItemDeselected(this.outerIdx, this.innerIdx);
final int outerIdx, innerIdx;
@override
List<Object?> get props => [outerIdx, innerIdx];
}
abstract class EditMasterEvent extends Equatable {
const EditMasterEvent();
}
class EditMasterItemDeselected extends EditMasterEvent {
EditMasterItemDeselected(this.outerIdx, this.innerIdx);
final int outerIdx, innerIdx;
@override
List<Object?> get props => [outerIdx, innerIdx];
}
Then, in some widget I call the child widget with
ChildWidget(itemSelectedEvent: (int i, int j) => EditItemDeselected(i, j))
with the parameter in ChildWidget
declared as final Function(int, int) itemSelectedEvent;
Now, inside ChildWidget
something like if (itemSelectedEvent is EditEvent)
does not work, neither does if (itemSelectedEvent is EditItemDeselected)
. It always results in false
.
The debugger shows for itemSelectedEvent
the value {_Closure} Closure: (int, int) => EditItemDeselected
Since you declared itemSelectedEvent
as dynamic Function(int, int)
itemSelectedEvent is EditEvent
will always return false since itemSelectedEvent
is a Function
and not an EditEvent
.
You need to call the function to get the return type. If you set itemSelectedEvent
to (int i, int j) => EditItemDeselected(i, j)
itemSelectedEvent(1, 2) is EditEvent
will return true.
Note: type checking is considered a bad practice in OOP. Because the switch cases need to be duplicated accross the code and if you add new types you need to adjust all of them.
class ChildWidget {
ChildWidget(this.itemSelectedEvent);
final Function(int, int) itemSelectedEvent;
void func(int i1, int i2) {
if (itemSelectedEvent(i1, i2) is EditEvent) {
// do if EditEvent
}
if (itemSelectedEvent(i1, i2) is EditMasterEvent ) {
// do if EditMasterEvent
}
}
}
Consider this instead:
abstract class EditEvent extends Equatable {
const EditEvent();
void doStuff();
}
class EditItemDeselected extends EditEvent {
EditItemDeselected(this.outerIdx, this.innerIdx);
final int outerIdx, innerIdx;
void doStuff() {
// do if EditEvent
}
@override
List<Object?> get props => [outerIdx, innerIdx];
}
class EditMasterItemDeselected extends EditEvent {
EditMasterItemDeselected(this.outerIdx, this.innerIdx);
final int outerIdx, innerIdx;
void doStuff() {
// do if EditMasterEvent
}
@override
List<Object?> get props => [outerIdx, innerIdx];
}
class ChildWidget {
ChildWidget(this.itemSelectedEvent);
final Function(int, int) itemSelectedEvent;
void func(int i1, int i2) {
itemSelectedEvent(i1, i2).doStuff()
}
}