Dart Cascade Notation
A cascade runs several operations on one object without repeating its name. The two dots start each new section of the chain.
A chain of writes on one buffer
Three write calls act on the same buffer. The object name appears only once.
void main() {
final buffer = StringBuffer()
..write('a')
..write('b')
..write('c');
print(buffer.toString());
}A cascade on a list returns the list
Each add call returns the list too, but the cascade result is the list itself. The variable holds the filled list.
void main() {
final nums = <int>[]
..add(1)
..add(2)
..add(3);
print(nums);
print(nums.length);
}The section value is the receiver
The write call on its own would return the buffer here, so a plainer proof uses identical. The cascade result is the very same buffer object.
void main() {
final buffer = StringBuffer();
final result = buffer..write('hi');
print(identical(result, buffer));
print(result.toString());
}A null-aware cascade
The receiver starts as null, so the write never runs and the result is null. After a real buffer is stored, the same shape writes normally.
void main() {
StringBuffer? target;
final result = target?..write('x');
print(result);
target = StringBuffer();
target?..write('y');
print(target.toString());
}Example
void main() {
final lines = <String>[]
..add('Name: Ana')
..add('Role: Dev');
final card = StringBuffer()
..write(lines[0])
..write(' | ')
..write(lines[1]);
print(card.toString());
}Key points
- Each section after the two dots acts on the same object.
- A cascade section ignores the return value of its own call.
- The whole cascade evaluates to the object it started on.
- A cascade can call methods and set fields on the receiver.
- A question mark before the two dots makes the cascade null-aware.
- A null-aware cascade on a null receiver does nothing and evaluates to null.
In this example, the first cascade fills a list with two lines of text. The second cascade writes both lines into one buffer with a separator between them. Each cascade evaluates to its own receiver, so lines holds the list and card holds the buffer.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท DartPad
Exercise
What does a cascade expression evaluate to?