“Dart Extension methods allow you to add functionality to an existing library.”
What does this really mean and let’s see it in action? 🥸
Consider a case where you need to right-align a set of characters by padding them with some specific characters or spaces on the left for a specified total length. Doing this will require us to customise the characters variable as below.
void main() {
var characters = “24”;
print(characters.padLeft(3, "0"));
}
The sample code above expose us to the use of extensions without even realising it. A more simpler example would be, let’s say it’s a requirement that we append “$” or user default currency to anywhere currency appears in our application. Instead of writing a custom helper method for this, we could simply extend the functionality of String
by creating an extension. Code snippet below:
extension on String{
String toCurrency(){
return "\$"+this;
}
}
void main() {
String balance = "20000";
print(balance.toCurrency());
}
Going a forward, the above use case can also be replicated to simplify importing and using assets file in your application. See example below.
Asset folder structure
project-folder/
| - assets
| - images
| - sample_image_1.jpg
| - sample_image_2.png
| - sample_image_3.svg
Also add the assets section to your application like this:
assets:
- assets/images/
In the above structure, we have three(3) files(images) in your assets folder. Traditionally, using this images in your application may require you writing sample code like below
Image.asset(
“assets/images/sample_image_1.png”,
),
Using Dart extension, we can reduce the tendencies of errors when importing assets by extending the functionality of String
.
extension StringExtensions on String {
String get png => "assets/images/$this.png";
String get svg => "assets/images/$this.svg";
String get jpg => "assets/images/$this.jpg";
}
Using asset image in our widget would now be as below
Image.asset(
“sample_image_1”.png,
),
Or
SvgPicture.asset(
“sample_image_1”.svg,
),
You have not only reduced the tendency of error but also the code looks cleaner and easier to understand.
Syntax of implementing extension methods
Dart extension methods was introduced in Dart 2.7 and below is the syntax for implementing one in your application.
extension <extension name> on <type> {
(<member definition>)*
}
Using Extensions on Widget
Let’s say you are using InkWell
widget to respond to touch events from users of your application and the UI
requirement is that splashColor
, highlightColor
, focusColor
and hoverColor
should be transparent. Now instead of repeating same functionality anywhere InkWell
widget appear in your application like below
InkWell(
focusColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
onTap: () {
},
child:Text(“Inkwell Code Snippet”),
)
We could simplify this further by creating an extension on InkWell
widget.
extension InkWellExtensions on InkWell {
InkWell get noShadow => InkWell(
focusColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
onTap: onTap,
child: child,
);
}
Now implementing this extension on InkWell widget anywhere in your application would be as below.
InkWell(
onTap: () {
},
child:Text(“Inkwell Code Snippet”),
).noShadow
You like what you see? 🤩🤩🤩
Don't feel like a superman just yet. wait until you experience DartX 😎
After exploring the Dart extensions and some use cases, it’s easy to say you need extensions in every data type that exist in dart.
A lot of things may be going through your mind right now
I can feel what's going on in your heart as you read this -> I see You want to make list operations more easier like reducing the amount of code needed to perform basic operations and more.
Before you get your hands dirty, DartX is telling you "I gat you Bro 😎"
Now let me introduce you to DartX Library.
Using DartX Library
DartX Library comes with a lot of extensions on various data types in dart. It allow developers to use readable single line operations on Dart collections.
To use DartX library, it is required that you add DartX dependency in your pubspec.yaml
file
dependencies:
flutter:
sdk: flutter
dartx: ^1.1.0
Let’s see some examples where DartX is used.
Using plain Dart, let’s get the first and last item from a list
. First we’ll need to check that the list is not empty to avoid state error or return a null if the list is empty before we go further to get the first or last item as required.
Sample code below:
final firstOrNull = list.isNotEmpty ? list.first : null;
final lastOrNull = list.isNotEmpty ? list.last : null;
This can be simplified using DartX below:
final firstOrNull = list.firstOrNull;
final lastOrNull = list.lastOrNull;
Example 2:
Let's say we want to filter a list for only odd-Indexed items. with plain Dart it would be
final oddItems = [];
for (var i = 0; i < list.length; i++) {
if (i.isOdd) {
oddItems.add(list[i]);
}
}
// or
final oddItems = list.asMap()
.entries
.where((entry) => entry.key.isOdd)
.map((entry) => entry.value)
.toList();
With DartX it's more simpler.
final oddItems = list.whereIndexed((x, index) => index.isOdd).toList();
// or
final oddItems = list.whereNotIndexed((x, index) => index.isEven).toList();
DartX shortens the implementation of collections in Dart. Thanks to the authors of this package.
Examples using DartX Library was collected from this medium post: “Dart collections with DartX extensions ” article by Anna Leushchenko
It's an amazing post with a lot of examples using DartX. I encourage you to go through it. There are a lot of examples there.
Until next time, Happy Coding.
#ClassicalDevs