what does the child class of Equatable pass to the super(Equatable class)?
Asked Answered
C

2

5

hi I am new with bloc in flutter and I'm trying to understand block timer In the doc of flutter_bloc and I would know what's this constructor class mean


@immutable
abstract class TimerState extends Equatable {
  final int duration;

//and this list props ??
  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));
}
Can answered 27/9, 2019 at 17:3 Comment(4)
Could you please define your question more specifically in context to your problem?Bayadere
why we add this : dart [List props = const []] Can
and what's this dart super([duration]..addAll(props)); meanCan
For anyone seeing this question when using equatable versions > 0.6.x (which you should be in 2020), this no longer applies and has since removed, in favor of requiring overloading a prop getter method.Duckboard
W
39

Update: For the new version of Equitable package >= v 0.6.0 read my article on Medium, for older version or deep understanding read this answer.


When your father gives you and your brother 2 gifts, both gifts are laptops but they are not the same type of laptops; you want to know are both gifts equal or not! So you will compare all aspects that important to you RAM, SSD, CPU.

on a paper: myLaptop: 16G/256G/i5 | myBrotherLaptop: 8G/512G/i5

Assuming your brain is using Dart language, and you thought of each gift as an object of this class:

class LaptopGiftClass {
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(this.ram, this.ssd, this.cpu);
}

then to compare Equailty of both gifts that created using the class above, Dart and other Object oriented languages e.g Java, C# are expecting you to create(override) these functions, in order to make these languages understand the objects and able to compare any two objects of same class:

@override
bool operator ==(Object myBrotherLaptop) =>
    identical(myLaptop, myBrotherLaptop) ||
    myBrotherLaptop is LaptopGiftClass &&
    runtimeType == myBrotherLaptop.runtimeType &&
    name == myBrotherLaptop.name;

@override
int get hashCode => name.hashCode;

if these lines scares you off, no one blame you, that's why nice people have created equatable package for us!

Equatable package is telling you "leave this scary job for me" But how to delegate the scary code to equatable package??! By doing two things:

  1. Make your class extends equatable: dart class LaptopGiftClass extends Equatable {...}
  2. Pass all properties that you need to compare with inside an array to the Equatable(the super/parent class) from moment one, so inside the constructor:
LaptopGiftClass(this.ram, this.ssd, this.cpu) : super([ram, ssd, cpu]);

your final class is:

class LaptopGiftClass extends Equatable {
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(this.ram, this.ssd, this.cpu) : super([ram, ssd, cpu]);

}

AND YOU ARE DONE! you can now check equality of the two gifts, just create the objects then compare:

LaptopGiftClass myLaptop = LaptopGiftClass(16,256,'i5');
LaptopGiftClass myBrotherLaptop = LaptopGiftClass(8, 512,'i5');

AND JUST BEFORE START COMPARING, your brother saw you, and because he is a gamer, he wants you to add more properties in this equality check: GPU and Screen_Resolution! your mother heard that and asked you to add price too!

Now you have a list of new props to compare: [GPU, Screen_Resolution, Price].

So because you follow clean code principle, you expected that, and you made the constructor able to get more properties to compare with:

// This only mean combine both lists
[ram, ssd, cpu]..addAll(myBrotherAndMotherProps) 

so your final class is:

class LaptopGiftClass extends Equatable {
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(
    this.ram, 
    this.ssd, 
    this.cpu, 
    // List of list => because we think "clean code" 
    // and maybe in the future we will send other data; NOT 
    // only an array(list)..
    // so we here sent the extra props we need to
    // compare 'myBrotherAndMotherProps', and 
    // as sometime brother and mother will not ask you 
    // to add props to compare, you give it a default value 
    // as empty "const []", why const here??! just for better 
    // performance as we are so soooo Professional!!

    [ List myBrotherAndMotherProps = const [] ],

 ) : super([ram, ssd, cpu]..addAll(myBrotherAndMotherProps));

 // WHY TO PASS FROM INSIDE THE CONSTRUCTOR? 
 // because Equatable needs them (required) 
 // and not at anytime but immediately inside the 
 // constructor of itself, so we made this 
 // chaining(constructor pass to another constructor)..
}

So it's obvious that the essintial properties are [RAM, SSD, CPU], but anything extra will be take into consideration too as we made the implementation clean, flexible, and scalable.

before adding this flexible code List<Object> get props => [RAM, SSD, CPU]..addAll(myBrotherAndMotherProps); these used to be EQUAL!!:

// Note first 3 are equal [ram, ssd, cpu]:
LaptopGiftClass myLaptop = LaptopGiftClass(16,256,'i5', ['Nvidia', 1080, '1200$']);
LaptopGiftClass myBrotherLaptop = LaptopGiftClass(16, 256,'i5', ['Intel HD', 720, '900$']);

myLaptop == myBrotherLaptop; // True without ..addAll(myBrotherAndMotherProps);
myLaptop == myBrotherLaptop; // False with ..addAll(myBrotherAndMotherProps);

Same happening with TimerState:

@immutable
abstract class TimerState extends Equatable {
  final int duration;

  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));
}

TimerState is implemented just like LaptopGiftClass above(last implementation). you can send props to it using the constructor:

TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));

so TimerState will pass props's list to its parent(super/ the Equatable/ what extended..) in this line like this: : super([duration]..addAll(props));

and in this timer example; duration is the basic prop, just like [RAM, SSD, CPU] to LaptopGiftClass.

and the hierarchy will be like this:

// Inside class Paused extends TimerState {...}
Paused(int duration) : super(duration); // super is TimerState

// then Inside abstract class TimerState extends Equatable {..}
TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props)); // super is Equatable

// Then Equatable will get props and deal with it for you...
Woolf answered 27/9, 2019 at 22:18 Comment(2)
Quite Nice Explanation.Philologian
that's some solid understanding there! nice one @Jehad Nasser :)Bubo
F
0

This tutorial use equatable: ^0.2.0, in this version when you want to override the hashcode and == operator you need to pass a List of the properties to the super constructor. Check out the docs.

Whit this in mind, he create a optional parameter called props, and pass to the super constructor a List that contains duration and all elements of the props parameter.

abstract class TimerState extends Equatable {
  final int duration;

  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));
}

In this way the class that extends TimerState can use the props optional parameter to pass other properties, and this properties would be added to the List that is passed to the super constructor of TimerState for use Equatable correctly.

So if you need a state that have other properties you need to do this:

class OtherTimerState extends TimerState {
  final int otherProperty1;
  final int otherProperty2;

  OtherTimerState(int duration, this.otherProperty1, this.otherProperty2)
      : super(duration, [otherProperty1, otherProperty2]);
}
Florence answered 27/9, 2019 at 19:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.