Lesson 18 min
Collection If, For & Spread
00:00 / 00:00
Declarative Collection Construction
Dart has three special operators for building collections declaratively inside literals: spread (...), collection if, and collection for. These are game-changers for Flutter widget trees.
These operators let you build dynamic lists, maps, and sets without intermediate variables or mutating operations. Your collection is constructed in a single, readable expression.
Spread Operator (... and ...?)
dartfinal first = [1, 2, 3]; final second = [4, 5, 6]; // Spread merges collections inline final combined = [...first, ...second]; // [1, 2, 3, 4, 5, 6] // Add extra items around the spread final withExtras = [0, ...first, 10]; // [0, 1, 2, 3, 10] // Null-aware spread (...?) — only spreads if not null List<int>? maybeList = fetchList(); final safe = [...?maybeList, 99]; // If null, just [99] // Works with Maps too final defaults = {'color': 'blue', 'size': 'medium'}; final custom = {...defaults, 'color': 'red'}; // overrides color
Collection If
dartbool isLoggedIn = true; bool isPremium = false; final menuItems = [ 'Home', 'Explore', if (isLoggedIn) 'Dashboard', // included only if true if (isLoggedIn && isPremium) 'Pro Features', if (!isLoggedIn) 'Sign In', // excluded when logged in ]; // Result: ['Home', 'Explore', 'Dashboard'] // With else branch final tabs = [ 'Feed', if (isPremium) 'Premium Content' else 'Upgrade to Pro', ];
Collection For
dartfinal names = ['Alice', 'Bob', 'Charlie']; // Build a list using a for loop inline final greetings = [ for (final name in names) 'Hello, $name!', ]; // ['Hello, Alice!', 'Hello, Bob!', 'Hello, Charlie!'] // Traditional range-based for final squares = [ for (int i = 1; i <= 5; i++) i * i, ]; // [1, 4, 9, 16, 25]
Combining All Three — Flutter Widget Tree Pattern
This is where the real power shows. In Flutter, you build widget trees dynamically:
dartWidget build(BuildContext context) { return Column( children: [ const HeaderWidget(), // Collection if — show banner only to new users if (user.isNewUser) const WelcomeBannerWidget(), // Collection for — render a card per item for (final item in cartItems) CartItemCard(item: item), // Spread — merge in a list of action buttons ...buildActionButtons(), const FooterWidget(), ], ); }
Real-World Example — Building a Navigation Menu
dartList<NavigationDestination> buildNavItems(bool isAdmin) => [ const NavigationDestination(icon: Icon(Icons.home), label: 'Home'), const NavigationDestination(icon: Icon(Icons.search), label: 'Search'), if (isAdmin) const NavigationDestination(icon: Icon(Icons.admin_panel_settings), label: 'Admin'), ...extraNavItems, ];
Summary
Collection operators transform Dart from a language where you mutate lists imperatively into one where you declare what a collection should look like. This is especially powerful in Flutter widget trees. Master these three operators and your Flutter code will become dramatically cleaner.