Helper options
A generic package created to handle your objects, widgets in a nicer way.
- Redundancy of getters with non-option approach
- Need to use liftNonNull or
!
with non-option approach because more likely that you will produce bugs as you have more getters and var names - Possibility to use arrow methods where its much shorter
- If dart ppl decide that for some crazy reason replace
!
with & you would need to do that in 1M places - You can add more helper methods into class rather than adding it separately into different files. (Open pull request)
- It avoids casting, so basically operator
!
is same asT
on an object which is defined asT?
by using optional we don't have this problem as there is no casting operation - General speaking Flutter ppl are not recommending the usage of
!
and saying that this should avoid as much as possible - Optionally allows the caller to continue a chain of fluent method calls. (arrow methods)
Note: This package also covers some helpful extensions to keep your code simple
Explanation with examples:
It is a generic class to determine the state of the object:
// A sample class object
class User {
const User(this.username);
final String username;
}
traditional way:
// in your business logic
User? user = await api.getUser();
if (user == null) {
// do this
final userName = user.username;
} else {
// do this
}
with helper_options:
// in your business logic
Option<User> user = Option.of(await api.getUser());
if (user.isPresent) {
// do this while getting value as
final userName = user.value.username;
} else {
// do this
}
Looks cool nah!!!
You may explore options too:
// this option class comes with other helper methods like
user.empty(); // Creates an empty Option.
user.filter(); // Returns an Option with this Option's value, if there is a value present and it matches the predicate. Otherwise, returns an empty Option.
user.flatMap(); // Returns an Option provided by applying the mapper to this Option's value,if present. Otherwise, returns an empty Option.
user.orElse(); // Returns this Option's value, if present. Otherwise, returns other.
user.orNull(); // Returns this Option's value, if present. Otherwise, returns null.
user.orElseThrow(); // Returns this Option's value, if present. Otherwise, throws the result of calling supplyError().
user.ifPresent(final val){
// Invokes consume() with this Option's value, if present.
// Otherwise, if orElse is passed, invokes it, otherwise does nothing.
}
OptionWidget:
In another example, we are going to have a super OptionWidget
to generate the Widget as your data is there:
Traditional way:
class CustomWidget extends StatelessWidget {
const CustomWidget({this.user});
final User? user;
bool get isEmptyUser => user == null;
@override
Widget build(final BuildContext context) {
if (isEmptyUser) {
return SizedBox();
}
return childWidget();
}
}
// and then calling in a parent data like this:
ParentWidget(
child: CustomWidget(user: user),
);
with CustomWidget:
ParentWidget(
child: OptionWidget<User>(
option: Option.of(user),
empty: final OffStage(), // it is an optional widget to place
builder: (final context, final user) {
return Child();
},
),
),
Note: You can use this function in a nicer way with all the objects including primitive data types or custom one