Chapter 2: Mastering Equality with the Equatable Package in Flutter Bloc
Welcome back to Chapter 2 of our Flutter Bloc State Management course! If you’ve been following along, we’ve set the foundation with an overview of Flutter Bloc, its significance, and why big companies trust it for state management. Today, we’re taking a closer look at an essential tool in Flutter Bloc’s toolkit: the Equatable
package.
In this post, we’ll talk about comparing objects in Dart, why object equality is so important in state management, and how Equatable
saves us from writing redundant, boilerplate code. By the end of this chapter, you'll have a solid understanding of object equality and know exactly when and how to use Equatable
in your Flutter Bloc projects.
Why Equality Matters in State Management
Imagine you’re designing a to-do app. Each time you add or remove a to-do item, the state of your app changes. If the state isn’t accurately updated or recognized, your app might behave unpredictably. This is where checking if two objects are equal or not becomes essential. In Dart, you might expect the equality operator (==
) to check for equality between two instances, but by default, it only checks if they’re the same instance in memory, not if they contain the same data.
Equality in Dart: The Basics
Dart provides two primary ways to check if objects are equal:
Equality Operator (
==
): Checks if two objects reference the same instance in memory.Hash Code: Helps compare objects based on their properties.
Example: The Equality Operator and Hash Code in Action
Let’s say we have a User
class with id
and name
properties. Here’s how we might check for equality without using Equatable
.
class User {
final int id;
final String name;
User({required this.id, required this.name});
}
void main() {
var user1 = User(id: 1, name: 'Alice');
var user2 = User(id: 1, name: 'Alice');
print(user1 == user2); // false - even though they have the same data
}
The result here is false
because, by default, Dart checks if user1
and user2
are the same instance in memory, which they’re not.
Implementing Equality Manually
One solution is to override the ==
operator and hashCode
in the User
class manually. Here’s how that would look:
class User {
final int id;
final String name;
User({required this.id, required this.name});
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is User && runtimeType == other.runtimeType && id == other.id && name == other.name;
@override
int get hashCode => id.hashCode ^ name.hashCode;
}
This works, but it’s a lot of code to write for every model, especially in larger applications. Here’s where Equatable
comes to the rescue.
Meet Equatable: Simplifying Object Equality
Equatable
is a package that makes it easy to compare objects by simply listing the properties that define equality. It saves us from writing the boilerplate ==
and hashCode
logic.
Installing Equatable
To get started, add Equatable
to your project by adding it to pubspec.yaml
:
dependencies:
equatable: ^2.0.3
After running flutter pub get
, you’re ready to start using Equatable
.
Implementing Equatable in Your Class
Now, let’s rewrite the User
class using Equatable
.
import 'package:equatable/equatable.dart';
class User extends Equatable {
final int id;
final String name;
User({required this.id, required this.name});
@override
List<Object?> get props => [id, name];
}
Let’s break down what’s happening here:
Inheritance: The
User
class now extendsEquatable
, which allows us to implement easy equality checks.props
: We override theprops
getter to list the properties (id
andname
) that should be considered when comparing instances.
Testing the Equatable Implementation
Now let’s see the result of comparing two instances with the same properties:
void main() {
var user1 = User(id: 1, name: 'Alice');
var user2 = User(id: 1, name: 'Alice');
print(user1 == user2); // true
}
With Equatable
, user1 == user2
now returns true
, as expected!
Challenge Time: Practice with Equatable
It’s your turn! Let’s go through a hands-on exercise to solidify your understanding of Equatable
.
Create a Class: Define a
Product
class with properties likeid
,name
, andprice
.Use Equatable: Extend
Equatable
and overrideprops
to include your properties.Test It Out: Create two instances with the same property values and test equality between them.
Here’s a template to get you started:
import 'package:equatable/equatable.dart';
class Product extends Equatable {
final int id;
final String name;
final double price;
Product({required this.id, required this.name, required this.price});
@override
List<Object?> get props => [id, name, price];
}
void main() {
var product1 = Product(id: 101, name: 'Laptop', price: 1500.0);
var product2 = Product(id: 101, name: 'Laptop', price: 1500.0);
print(product1 == product2); // true
}
Try adding or changing properties in the Product
class and see how Equatable
handles it automatically.
Why Equatable Is Essential for Flutter Bloc
When managing state with Bloc, your states and events are frequently compared. Without Equatable
, you’d have to override ==
and hashCode
in every state and event class, which could lead to bulky, error-prone code. With Equatable
, state and event comparison are straightforward and requires minimal setup. This makes your Bloc codebase cleaner, more efficient, and easier to maintain.
Example: Using Equatable in Bloc States
Let’s look at a small example of how Equatable
fits into a Bloc setup. Suppose we have a counter app where our states represent different values of a counter.
import 'package:equatable/equatable.dart';
abstract class CounterState extends Equatable {
const CounterState();
}
class CounterValue extends CounterState {
final int value;
const CounterValue(this.value);
@override
List<Object?> get props => [value];
}
Here, CounterValue
extends CounterState
, which itself extends Equatable
. Thanks to Equatable
, our Bloc now knows when two states are effectively the same, leading to smoother, optimized performance in state transitions.
Wrapping Up
Today we learned:
Why object equality is crucial in state management.
How to manually override equality in Dart.
How
Equatable
simplifies equality checks, reducing boilerplate code and making comparisons effortless.How to apply
Equatable
in state classes within Bloc for optimal performance.
Equatable is a small but powerful tool, making equality in Flutter Bloc more straightforward and intuitive. Spend a few minutes practicing what you’ve learned today. Try adding Equatable
to different classes in your project, and see the difference in code cleanliness and readability.
Subscribe to my newsletter
Read articles from Md. Al - Amin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Md. Al - Amin
Md. Al - Amin
Experienced Android Developer with a demonstrated history of working for the IT industry. Skilled in JAVA, Dart, Flutter, and Teamwork. Strong Application Development professional with a Bachelor's degree focused in Computer Science & Engineering from Daffodil International University-DIU.