We can use the forEach loop with any type of collection in Flutter. In Dart we have seen many types of implementations.
The e-commerce app we have been building has many parts. We have used the Provider package to provide values and notify listeners.
However, every component like product, cart and order has a unique relationship with each other.
For example, when we keep adding the products, they assemble in the Cart page.
After that, we can see all the products in one place. And, finally we can order them.
For instance, we have added a few products and the cart page displays them as follows.
![Cart page where order can be placed](https://i0.wp.com/sanjibsinha.com/wp-content/uploads/2022/07/Cart-page-where-order-can-be-placed.webp?ssl=1)
As an outcome, now we can “Order them” by pressing the button.
However, to do that, we have to use the forEach method.
But how?
We will see in a minute.
Before that let’s see how it looks when we press the order button.
![Push replacement named Flutter - second example](https://i0.wp.com/sanjibsinha.com/wp-content/uploads/2022/07/Push-replacement-named-Flutter-second-example.webp?ssl=1)
How forEach in Flutter works?
Let’s see how the forEach method in Flutter works.
As we said, the forEach method which is actually a Dart concept of looping. Moreover, it works with any type of collection.
In our case, it happens the same way.
Let’s see the code of the cart page first.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './../models/cart.dart' show Cart;
import '../controllers/cart_item_page.dart';
import './../models/orders.dart';
class CartScreen extends StatelessWidget {
static const routeName = '/cart';
const CartScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final cart = Provider.of<Cart>(context);
return Scaffold(
appBar: AppBar(
title: const Text('Your Cart'),
),
body: Column(
children: <Widget>[
Card(
margin: const EdgeInsets.all(15),
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
'Total',
style: TextStyle(fontSize: 20),
),
const Spacer(),
Chip(
label: Text(
'\$${cart.totalAmount.toStringAsFixed(2)}',
style: TextStyle(
color: Theme.of(context).colorScheme.background,
),
),
backgroundColor: Theme.of(context).primaryColor,
),
TextButton(
child: const Text('ORDER NOW'),
onPressed: () {
Provider.of<Orders>(context, listen: false).addOrder(
cart.items.values.toList(),
cart.totalAmount,
);
cart.clear();
},
)
],
),
),
),
const SizedBox(height: 10),
Expanded(
child: ListView.builder(
itemCount: cart.items.length,
itemBuilder: (ctx, i) => CartItem(
cart.items.values.toList()[i].id,
cart.items.keys.toList()[i],
cart.items.values.toList()[i].price,
cart.items.values.toList()[i].quantity,
cart.items.values.toList()[i].title,
),
),
)
],
),
);
}
}
In the above code we see that the button calls a method. As a result the method works upon the “Orders” model class, where we have defined the method.
Firstly, let’s see the code of the Orders model class.
void addOrder(List<CartItem> cartProducts, double total) {
_orders.insert(
0,
OrderClass(
id: DateTime.now().toString(),
amount: total,
dateTime: DateTime.now(),
products: cartProducts,
),
);
notifyListeners();
}
// for full code please visit this GitHub Repository
As we see the method passes two methods.
One is the “CartItem” List which is a model class and a double value “total”.
For that reason, we need to go to the “CartItem” to find how this method returns the total amount.
double get totalAmount {
var total = 0.0;
_items.forEach((key, cartItem) {
total += cartItem.price * cartItem.quantity;
});
return total;
}
// for full code please visit this GitHub Repository
Finally here we have the forEach to get the total amount of the ordered items.
To understand the full workflow, we need to see this branch of the GitHub Repository.
Leave a Reply