Q&A
What is the List addAll() method in Dart?
Overview
When you need to append multiple items at once rather than one by one, addAll is the idiomatic choice. It avoids a loop of add() calls, is more expressive, and works with any Iterable input - lists, sets, maps' values, generators, etc.
graph LR
A["list.addAll(iterable)"] --> B["Appends every element in order"]
B --> C["Original list modified in place"]
B --> D["Works with List, Set, any Iterable"]
A -.alternative.-> E["[...list, ...other] (spread, returns new list)"]
style A fill:#1e1b4b,color:#fff
Basic Usage
List<int> numbers = [1, 2, 3];
numbers.addAll([4, 5, 6]);
print(numbers); // [1, 2, 3, 4, 5, 6]
The elements are appended to the end in the order they appear in the argument.
Adding from Different Iterable Types
List<String> fruits = ["apple", "banana"];
// From another list:
fruits.addAll(["cherry", "date"]);
// From a Set:
fruits.addAll({"elderberry", "fig"}); // order from the set
// From a generator / Iterable expression:
fruits.addAll(["grape", "honeydew"].where((s) => s.length > 5));
Because the argument is typed as Iterable<E>, any iterable works - not just lists.
addAll vs add
List<int> a = [1, 2];
a.add(3); // adds a single element → [1, 2, 3]
a.addAll([4, 5]); // adds multiple → [1, 2, 3, 4, 5]
// Crucially: add([4,5]) would add the LIST ITSELF as one element:
a.add([4, 5]); // [1, 2, 3, [4, 5]] - nested, NOT what you usually want
This is the most common mistake - calling add with a list when addAll is needed.
addAll vs the Spread Operator (non-mutating)
addAll modifies the existing list. If you need a new list, use the spread operator:
final combined = [...list1, ...list2]; // new list, originals untouched
list1.addAll(list2); // mutates list1
Choose based on whether you need mutation or immutability.
Fixed-Length Lists
Fixed-length lists (created via List.filled without growing) cannot be extended:
final fixed = List<int>.filled(3, 0); // [0, 0, 0], fixed length
fixed.addAll([1, 2]); // ❌ UnsupportedError: Cannot add to a fixed-length list
Only growable lists (the default [] or List<T>()) support addAll.
Related Methods
| Method | Purpose |
|---|---|
add(element) |
Append a single element |
addAll(iterable) |
Append all elements of an iterable |
insert(index, element) |
Insert at a specific position |
insertAll(index, iterable) |
Insert all elements of an iterable at a position |
+ operator |
Returns a new concatenated list (non-mutating) |
[...a, ...b] spread |
New list combining multiple, non-mutating |
// insertAll - place at a specific index:
final list = [1, 2, 5, 6];
list.insertAll(2, [3, 4]); // [1, 2, 3, 4, 5, 6]
Why This Matters in Interviews
Flutter/Dart interviews use addAll to test collection manipulation and the mutating-vs-non-mutating distinction. Key points: addAll mutates the list and accepts any Iterable; confusing add(list) with addAll(list) is the classic bug (the former nests the list as a single element); addAll requires a growable list; and the spread-operator alternative returns a new list rather than mutating. Knowing insertAll for mid-list insertion rounds it out.
Common Pitfalls
- Using
add(anotherList)instead ofaddAll(anotherList)- nests the list instead of merging. - Calling
addAllon a fixed-length list →UnsupportedError. - Expecting
addAllto return a new list (it returnsvoidand mutates in place). - Using
addAllwhen you want a fresh immutable list (use spread instead).
References
- Dart
List.addAll: https://api.dart.dev/stable/dart-core/List/addAll.html - Dart collections overview: https://dart.dev/guides/libraries/library-tour#collections