Search code examples
apiflutterflutter-provider

Flutter Passing Data Between Screens


I am developing a flutter app which shows an order list and it gonna show respective order details onTap, as I have seen a lot of examples showing on how to pass data from the list screen to the screen that shows the details of that object passing in which we can read the data by widget.obj.name. However, in my case, I would like to pass the id of one of the orders and here I was able to get the order id from the previous screen with widget.orderId but I am stuck with retrieving the details by calling the get order details API.

To further explain I will show my codes here:

In orderlist.dart,

        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => OrderDetail(
                      orderId: order.id,
                      onRefresh: onRefresh,
                    )),
          );
      },

In order_detail.dart, I was trying to build the UI and I am getting null for model.orderItem.toString(). It works perfectly fine when I try to run Services().getOrderDetails() API directly but since I have the OrderItem model and I shall use it with provider.

 @override
  Widget build(BuildContext context) {
       return ListenableProvider<OrderItemModel>(
          create: (_) => OrderItemModel(),
          child: Consumer<OrderItemModel>(
          builder: (context, model, child) {
              print("orderItem: " + model.orderItem.toString());
          },
      ));
  }

I am getting the following error: Unhandled Exception: Error: Could not find the correct Provider above this OrderDetail Widget. This likely happens because you used a BuildContext that does not include the provider of your choice. There are a few common scenarios:

  • The provider you are trying to read is in a different route. Providers are "scoped". So if you insert of provider inside a route, then other routes will not be able to access that provider.
  • You used a BuildContext that is an ancestor of the provider you are trying to read. Make sure that OrderDetail is under your MultiProvider/Provider.This usually happen when you are creating a provider and trying to read it immediatly.

I have tried with the solution provided by Flutter but it still gave me the same error. Is there anything need to be done in the orderlist.dart part in order to call OrderItemModel provider in orderdetails.dart? Did i miss out anything?


Solution

  • Summary: move ListeableProvider a level higher (in orderlist.dart), where the route is pushed (OrderDetail should be its child).

    I think this may be because the OrderDetail is not a child of OrderList or whichever widget has the onTap action. This happens because you are specifying a route where OrderDetail is the root and it has no idea about the provider of the other widget. You will need to wrap it into a ChangeNotifierProvider (https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifierprovider or what you are using, ListeneableProvider) and build Order Detail there. It will look something along the lines of:

        ....
        builder: (_) => ChangeNotifierProvider.value(value: model, child: OrderDetail(...));
    

    The model will be coming from the OrderList which I am assuming is the provider.

    And in OrderDetail, you will need a Consumer<OrderItemModel> instead of the ListeneableProvider.