5

I know there have been certain questions on state management in flutter, but none of them seemed to solve my use case.

Recently I was building an app based on E-commerce and encountered this real need for state management. I had 2 pages,

  1. One is the products page, where I add a product to the cart.
  2. Second is the cart page, where I see products added recently to cart.

prod and cart page

Users can add the product to the cart and then navigate to the cart. In the cart page, they can also increase or decrease the quantity of the item.

As you can see, initially yellow item was added to the cart with quantity 3, but in the cart page, user pressed the (-) button and reduced the quantity to 1. Now if the user presses the back button, then the state of the yellow product will be still 3 on the products page. Similar situation with the pink product.

Hence I tried to resolve this using normal setState and some global data structures to keep track of the quantity. But as my app grew big, its really hard to maintain the state across the pages. I have read about different state management solutions like redux, BloC pattern, Provider, ... but I am not clear how to use any of them in my use case. Could anyone with experience, break down the rock and help me digest?

Any sample code and explanation about how to solve this would be appreciated!

Hope my problem is clear!

ANUP SAJJAN
  • 1,458
  • 13
  • 17

2 Answers2

1

ANUP SAJJAN to achieve this you can use Provider package. See these codes examples according to your case:

import 'package:flutter/material.dart';

import 'models/cartmodel.dart';

class AppState with ChangeNotifier {
  List<CartModel> _cartModel = new List<CartModel>();

  // Cart data list
  List<CartModel> get getCart => _cartModel;

  // Add item to cart
  addToCart(CartModel value) {
    _cartModel.add(value);
    notifyListeners();
  }

  // Remove item to cart
  removeToCart(CartModel value) {
    _cartModel.remove(value);
    notifyListeners();
  }
}

Create an instance in main.dart:

runApp(
  ChangeNotifierProvider<AppState>(
      create: (_) => AppState(),
      child: MyApp(),
    ),
)

You can now control the state :

@override
Widget build(BuildContext context) {
  final appState = Provider.of<AppState>(context);
  ...
  // manipulation
  appState.getCart
  appState.addToCart(value)
  appState.removeToCart(value)
  ...
}
Jhakiz
  • 1,519
  • 9
  • 16
  • Thank @Hakiza, I am relatively new to provider. But as far as I imagine, I have a list of products and my code base has onTap listeners on each of the products for increment and decrement. So how do your code relate to listening change to each product? I mean are you subscribing for receiving some notifier when something changes to each product? – ANUP SAJJAN Jul 08 '20 at 07:58
  • Basically, how are you linking both yellow product in "Products page" and "cart page" to maintain same state? – ANUP SAJJAN Jul 08 '20 at 07:59
  • The list of products is really different from that of cart; in the cart you need the product ID and the quantity. When increment or decrement listeners are handled, the AppState class will notifier all changes to subscribers(pages). You can use the same way as in the above example for Products list. – Jhakiz Jul 08 '20 at 09:04
0

The state is really a vehicle to control state of one screen, not a data storage. You probably shouldn't use State in this case, but rather a database. When a user is composing their cart, you create a cart record either on the user's device SQLite, or in the cloud (Firebase?). This may seem as an overkill at first, but consider that besides having a persistent storage that you can access from anywhere, you also get user behaviour data, i.e. what they added, how they proceeded, and how many dropped off.

As for the technical side of this, in Flutter it is common to use Providers. For me, the biggest benefit is business logic encapsulation. If you don't, your specific database logic will be all over the presentation layer, and should you want to change something, you will be in trouble :)

Here is a good article regarding providers.

Dmitri Borohhov
  • 1,513
  • 2
  • 17
  • 33
  • I agree that by using a db or cloud you might get an insight into user behaviour. But here the problem is, if he goes back to from cart to products page, then state should update, and when I have around 1000+ products, maintaining a track of all, and finding a relation would be cumbersome, wouldn't it be? – ANUP SAJJAN Jul 08 '20 at 07:48
  • Not really. Each product has an id, so all you need to do is to store a list of product ids and quantities in the cart. The cart should also contain a user (or session) id so that the right cart is brought up for the current user. – Dmitri Borohhov Jul 08 '20 at 08:35
  • Well yeah lets say new updated quantity is present in db for every product, but when user presses back button in cart, products page opens up from the navigation stack showing the old state itself. Now how do you update the new quantity ? – ANUP SAJJAN Jul 08 '20 at 08:58
  • For continuous updates, you would need a Stream and a Streambuilder widget which updates every time there is a change. – Dmitri Borohhov Jul 08 '20 at 09:08