Easily Understand Dart’s Extension Methods For Flutter
Unleash the power of Dart’s extension methods in Flutter to boost productivity
As consumers, we use many products in our day-to-day living- be it something as small as headphones or a jumbo car. But ahead of being consumers, we are humans before anything else. Each with a different and unique personality. 😎
Yes, we all do it to make the product truly ours.
Let’s understand this better by using the instance as an example. Consider that we want to perform any specific/new operation on the String class and we want it to be used from many places inside the app. In order to do this, we would first be creating a Helper or Utility class like this:
void main() {
print(StringUtil.isValidName('Pizza'));
}
class StringUtil {
static bool isValidName(String str) {
return !str.contains(new RegExp(r'[0–9]'));
}
}
It's all good. No harm in doing this. 👍
But look at the problem here. 😦
We may end up writing all helper methods like this in one single class. For better readability, we may also create another StringUtil class like shown in the example above and general methods in Util class only.
But calling the extra method from another class is something that doesn’t stand true to the essence of Object-oriented programming. Because we are used to perform an operation on the actual instance of an object like so:
myStr.toLowerCase();
myStr.isEmpty;
So how about if we could do this with our own custom methods?
Unfortunately 😦
You may not add your custom methods to the existing Dart files or any library(You don’t own the source code) and the Dart team or 3rd Party library does not know what you will need in advance.
Fortunately 😃
There is a solution to this 🤞
Do you want to stay updated in Flutter world? Please click on subscribe button to get an email when the new tutorial is published.
Presenting Extension Methods
The feature named Extension methods, Introduced in Dart 2.7 allows us to add new functionality to already available libraries. Although it does not allow us to modify existing code directly, It gives us the ability to customize a class in a way that we can read and use it easily.
We can also write an extension for getters, setters, and operators as well, these are called Extension members. It has been named ‘Extension methods’ so that developers coming from Kotlin, C# can also relate to it.
⚫️ Look at the syntax first-
extension <extension name> on <type> {
(<member definition>)*
}
Now the example -
extension ExtendedString on String {
bool get isValidName {
return !this.contains(new RegExp(r'[0–9]'));
}
}main() {
print('Pizza'.isValidName);
}Output: True
Short explanation -
With this, we have created our first extension named as ExtendedString on a String class. Inside this, we have written a getter which determines whether an instance of String contains a valid name or not using the given keyword.
If you notice carefully we have actually written extended getter.
⚫️ Writing extended methods -
What if you want to concatenate a string with some predefined string. Let’s write an extended method for it.
extension ExtendedString on String {
String prefixWith(String prefix) {
return '$prefix $this';
}
}main() {
print('Pizza'.prefixWith('I love'));
}Output: I love Pizza
⚫️ Can we do the same with just an operator?
Yes. Here it is.
extension ExtendedString on String {
String operator &(String prefix) => '$prefix $this';
}main() {
print('Pizaa'&'I Love');
}Output: I love Pizza
API conflicts
There are chances that the same extension methods are created in different Dart files and you may face API conflicts. For example
-------------------------------------------------------
File: extended_strings.dartextension ExtendedString on String {
bool get isValidName {
return !this.contains(new RegExp(r'[0–9]'));
}
}--------------------------------------------------------File: my_extended_strings.dartextension MyExtendedString on String {
bool get isValidName {
return !this.contains(new RegExp(r'[0–9]'));
}
}-------------------------------------------------------main() {
print('Pizza'.isValidName);
}
The same extension method isValidName is created on String class in two different files which create ambiguity and we have invited conflict.
How do we resolve API conflicts
Option 1: Hide it
import 'extended_strings.dart'; //Has isValidName
import 'my_extended_strings.dart' //Has isValidName but now hide it.
Option 2: Write extension explicitly
import 'extended_strings.dart'; //Has isValidName
import 'my_extended_strings.dart' //Has isValidName main() {
print(ExtendedString('Pizza').isValidName);
print(MyExtendedString('Pizza').isValidName);
}
Flutter advantage
How can we unleash the full power of Extension methods? Let’s see it.
Suppose you want different alignment of children in the column. Normally you would do something like this.
Before
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: AlignmentDirectional.centerStart,
child: Text('I am aligned at start'),
),
Align(
alignment: AlignmentDirectional.centerEnd,
child: Container(height: 20,width:50,color:Colors.amber),
),
],
)
After — now with extension methods,
extension ExtendedText on Widget {
alignAtStart() {
return Align(
alignment: AlignmentDirectional.centerStart,
child: this,
);
}
alignAtEnd() {
return Align(
alignment: AlignmentDirectional.centerEnd,
child: this,
);
}
}------------------------------------------------------------Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('I am aligned at the start').alignAtStart(),
Container(height: 20,width:50,color:Colors.amber).alignAtEnd()
],
)
You do clearly see the difference, right?
Additionally you get this great Autocomplete for free!
Full code can be found here 👇
Some useful extensions can be found here 👇
Goodbye
Thanks for reading. If you found this article to be helpful please share it with your friends.
For more about programming, follow me and Aubergine Solutions, so you’ll get notified when we write new posts.
Little about me
Hi, I am Pinkesh Darji. I write about Flutter at https://flutterbeads.com/. I love to solve problems using technology that improves user’s life on a major scale. Over the last several years, I have been developing and leading various mobile apps in different areas. More than just programming, I love to write technical articles.