Exploring the beauty of Dart Extensions and DartX Library

Exploring the beauty of Dart Extensions and DartX Library

“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