2

I saw the following code in a Flutter tutorial .

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

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

I cannot understand the code in the constructor. Can somebody please explain what is happening here ?

2 Answers 2

4

This constructor has 2 positional parameters:
1st is this.duration, which will initialise final int duration field. this.something in constructor means that it will initialise the field with name something of created instance.
2nd parameter is optional positional, because it is listed in square brackets. It is a List without type parameter, so this list can contain mix of any objects. If value of this list is not set then default value of empty list is used (= const []). const keyword here is used because by dart rules default parameters of constructors must be compile-time constants.

So calls TimerState(10) and TimerState(10, []) will return equal results.

Next part is call to constructor of parent class Equatable. This class belongs to equatable package. This class is made to simplify overriding operator == by removing boilerplate code. Instead of describing each field in comparison, it puts values of all fields to one list and compares this list.
Call looks like : super([duration]..addAll(props)).
Here [duration] means creation of List containing duration.
..addAll(props) takes created list with duration, adds everything from props list passed in TimerState constructor, and returns this new list with duration and props inside. It is done only to simplify comparison of TimerState objects for equality.

So by calling TimerState(10, [prop1, prop2, prop3]) you will create a TimerState with duration set to 10, which will call Equatable constructor with parameter [10, prop1, prop2, prop3]

I hope I did not confuse you even more :)
I think usage of Equatable in this example is overkill, because there is only one actual property and props in TimerState are never used

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the great explanation. It all makes sense once I read your answer except for one thing; the usage of .. (cascade) operator here. I thought it would be used to do multiple operations on the same object like list.add(x)..add(y). Here add(x) returns void, so .. needs to be used. But in the code above, [duration]..addAll(props) is used. Why does [duration].addAll(props) throw an error? Doesn't [duration] return a List object so that we can call the addAll method directly ?
@humblePilgrim addAll returns void too, so cascade operator is required to return a list
I have also seen const <dynamic>[]. Is that the same thing as const []?
0

This might also be better written these days using the spread operator:

super([duration]..addAll(props))

becomes

super([duration,...props])

At least if I'm understanding the syntax properly. If not, someone will whack me with the appropriate ruler. :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.