Flutter: Equatable & It’s usage in Bloc

Jitesh Mohite
FlutterWorld
Published in
3 min readJun 10, 2021

In Dart or any language, We always find it difficult to compare objects and return results. If we do not implement it correctly then in the long term you will face a lot of problems, as this will provide the wrong output as data is not compared as expected, Let's see an example of how dart solve it?

First, we will see the problem which we will be trying to fix

void main() {
User user = User('jitsm555');
print(user == User('jitsm555')); // Output: false
}

class User {
final String name;

User(this.name);
}

As you can see above, both objects having the same values, but while comparing they returns false. This happens because both have different hashcode internally.

Solution!!!

import 'package:equatable/equatable.dart';

void main() {
User user = User('jitsm555');
print(user == User('jitsm555')); // Output: true
}

class User extends Equatable {
final String name;

User(this.name);

@override
List<Object?> get props => [name];
}

Object and data comparison is always hard to do, So here comes theEquatable as it overrides == and hashCode internally, which solves our purpose of data comparison and eventually will save a lot of boilerplate code.

If we are not using theEquatable then we have to write our own code for object comparison like

class User {
final String name;

User(this.name);

@override
bool operator ==(Object other) => other is User &&
name == other.name;

@override
int get hashCode => name.hashCode;
}

So, coming to the usage of theEquatable in Bloc, becomes important as it updates the state as per the object changes, so before jumping on it, I recommend you to read the blog on the Bloc Mystery | Part 1 first, as the below topic required some knowledge around it.

Dependency:

To use theEquatable add the dependency in pubspec.yaml file

dependencies:
equatable: ^2.0.2

In Bloc, we have to extend Equatable to States and Events classes to use this functionality. This helps us when it comes to stream as we need to decide state updation based on it.

Ex:

abstract class LoginState extends Equatable {}

LoginState will not make duplicate calls and will not going to rebuild the widget if the same state occurs. Now, think we haven't used Equatable it here, then how many times Widget will be rebuild.

Equatable comes with props property which have its own purpose in object comparison, I have seen developers been neglecting this, and later face a lot of time in debugging.

Let’s see props usage in Equatable and what makes it special

Define State without props:

class LoginLoadSuccess extends LoginState {
final String name;
final List<User> users;
const LoginLoadSuccess([this.name, this.users = const []]);
}

Define State with props:

props declared when we want State to be compared against the values declared inside props List

class LoginLoadSuccess extends LoginState {
final String name;
final List<User> users;
const LoginLoadSuccess([this.name, this.users = const []]);
@override
List<Object> get props => [name, users];
}

props property decides which objects we should consider for object comparison, Suppose if we remove the name from the props then State will only consider the users field, avoiding the name field for object comparison. That is why it's important to use it carefully, as one mistake can cost a lot of time.

Bloc Stream Usage:

As we extending State with Equatable which makes a comparison of old state data with new state data.

For example, let's look at the below example here LoginState will build a widget only once, which will avoid the second call as it is duplicated.

@override
Stream<LoginState> mapEventToState(MyEvent event) async* {
final List<User> users = [User(), User()];
yield LoginLoadSuccess(users);
yield LoginLoadSuccess(users);
/// Second call will be avoided, means widget will not rebuild
}

--

--

Jitesh Mohite
FlutterWorld

I am technology enthusiastic, want to learn things quickly and dive deep inside it. I always believe in developing logical things which makes impact on end user