Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The .. (cascade) operator in Dart evaluates an expression, performs a sequence of method invocations or member assignments on the resulting object, and returns the original object reference rather than the return values of the invoked members. It effectively overrides the standard return type of a method or assignment, forcing the expression to yield the receiver object.

Syntax

receiverExpression
  ..memberAssignment = value
  ..methodInvocation()
  ..getterInvocation;

Execution Mechanics

  1. Receiver Evaluation: The receiverExpression on the left side of the first cascade operator is evaluated exactly once.
  2. Sequential Execution: The operations on the right side of the .. operators are executed in top-down order against the evaluated receiver.
  3. Return Value Discard: The standard return values of the individual methods or assignments within the cascade chain are discarded.
  4. Final Yield: The entire cascade expression resolves to the reference of the original receiver object.

Operator Precedence

The cascade operator has very low precedence, sitting just above assignment operators (=, +=, *=, etc.). Standard member access (.) has higher precedence than cascade (..). Because of this precedence, chaining a standard dot operator directly inside a cascade section applies the dot operation to the return value of the preceding method, forming a single, chained cascade section.
// The compiler parses `configure().execute()` as a single cascade section.
// execute() is invoked on the return value of configure().
// The return value of execute() is then discarded by the cascade.
// The entire expression yields the ReceiverObject instance.
ReceiverObject()..configure().execute();
If the intent is to perform a standard operation on the result of the entire cascade, parentheses are required around the cascade expression to enforce scoping.
// Parentheses ensure the cascade completes before the standard method invocation.
// execute() is invoked on the ReceiverObject instance yielded by the cascade.
(ReceiverObject()..configure()).execute();

Null-Aware Cascade (?..)

Dart provides a null-shorting variant of the cascade operator, denoted as ?...
nullableReceiverExpression
  ?..methodInvocation()
  ..memberAssignment = value;
If nullableReceiverExpression evaluates to null, the execution immediately short-circuits. None of the subsequent cascade operations (whether prefixed by ?.. or ..) are executed, and the entire expression evaluates to null. The ?.. operator is only required on the first operation in the cascade sequence; subsequent operations on the same receiver safely use the standard .. operator because the short-circuiting guarantees the receiver is non-null if execution proceeds.

Nested Cascades

Cascades can be nested when an expression within a cascade requires its own cascade sequence. Because the cascade operator binds to the root (farthest) receiver of the cascade expression, nesting requires explicit scoping using parentheses.
receiverExpression
  ..methodInvocation()
  ..nestedObjectProperty = (NestedObject()..nestedMethod());
Without the parentheses (..nestedObjectProperty = NestedObject()..nestedMethod()), the Dart compiler parses the expression sequentially and applies ..nestedMethod() to the root receiverExpression rather than the newly instantiated NestedObject.
Master Dart with Deep Grasping Methodology!Learn More