Equatable in Flutter: A Complete Guide
What is Equatable? How to use it? What's the difference between using ( == & hashcode ) vs. ( Equatable )

Search for a command to run...
What is Equatable? How to use it? What's the difference between using ( == & hashcode ) vs. ( Equatable )

No comments yet. Be the first to comment.
Lessons from Code, Content, and Consistency

Reliability basics: Outbox pattern + why it matters

Introducing Kafka/Redpanda + move to event-driven workflow

Connect Orders โ Inventory (first working service-to-service flow)

Inventory service + gRPC + proto contracts

== and hashcode.overriding these methods we can compare our instances.Car.dart
class Car {
final String carName;
final String carImage;
const Car({required this.carName, required this.carImage});
}
main.dart I've created two Car objectsfinal Car audi = Car(carName: "Audi", carImage: "assets/images/audi.png");
final Car bmw = Car(carName: "BMW", carImage: "assets/images/bmw.png");
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CarWidget(
carImage: audi.carImage,
carName: audi.carName,
),
SizedBox(
width: 200,
height: 50,
child: ElevatedButton(
onPressed: () {
compareObjects(context);
},
child: Text("Compare"),
),
),
CarWidget(
carImage: bmw.carImage,
carName: bmw.carName,
),
],
),
),
),
);
}
}

Now Let's implement Compare function :
compareCars(BuildContext context) {
if (audi == bmw) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("YES, They are EQUAL")));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("NO, They are not EQUAL")));
}
}
Compare buttonElevatedButton(
onPressed: () {
compareCars(context);
},
child: Text("Compare"),
),
NO, They are not EQUAL Scaffold message 
// Creating two same car
final Car audi = Car(carName: "Audi", carImage: "assets/images/audi.png");
final Car audi2 = Car(carName: "Audi", carImage: "assets/images/audi.png");

audi and audi2, what should be the output according to you?. Let's check!!compareCars(BuildContext context) {
if (audi == audi2) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("YES, They are EQUAL")));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("NO, They are not EQUAL")));
}
}
Output

Strange ๐ค!! It's still giving a They are Not Equal message. It's because under the hood Dart doesn't compare the objects by their value.
audi and audi2 both objects are in different memory locations. It doesn't matter if they have exact same values. They both will be considered as different objects.== and hashcode methods.Car.dart model class.class Car {
final String carName;
final String carImage;
const Car({required this.carName, required this.carImage});
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Car &&
runtimeType == other.runtimeType &&
carName == other.carName &&
carImage == other.carImage;
@override
int get hashCode => carName.hashCode ^ carImage.hashCode;
}
== method do is, It will compare objects by their type, and values.
== method and also within the hashcode method.Equatable comes in!Equatable simplify the above process by overriding == and hashcode for you.equatable packageequatable: ^2.0.3
props.import 'package:equatable/equatable.dart';
class Car extends Equatable {
final String carName;
final String carImage;
const Car({required this.carName, required this.carImage});
@override
List<Object?> get props => [carName, carImage];
}
props is a getter method that will return List<Object>. Here Object can be of any type (like : int,double, list etc). You have to simply return a list of all the objects that are available in your class (carName and carImage in our case).
Note: Equatable is designed to only work with immutable objects so all member variables must be final
EquatableMixin :EquatableMixin mixin.class Car extends Object with EquatableMixin {
final String carName;
final String carImage;
const Car({required this.carName, required this.carImage});
@override
List<Object?> get props => [carName, carImage];
}
Equatable also provide one additional functionality i.e stringify method.toString method simply override the stringify method -class Car extends Object with EquatableMixin {
final String carName;
final String carImage;
const Car({required this.carName, required this.carImage});
@override
List<Object?> get props => [carName, carImage];
@override
bool get stringify => true;
}
toString method with all the fields which we have in our class.