Data is showing only after hot reload

920 views Asked by At

I'm new to flutter and amplify. I'm trying to do an app using flutter and amplify as backend. I want to retrieve data from three datastore table at once and put them in to a List<Map<String, dynamic>>. I can read data from the List but the data display only when I press refresh or hot reload. I think maybe the mistake is the way I put the setstate? Could anyone tell me what I did wrong? Any help would be much appreciated!

Here is my code

  late StreamSubscription _subscription;
  List<Map<String, dynamic>> _orderList = [];

  @override
  void initState() {
    super.initState();
    _subscription =
        Amplify.DataStore.observe(OrderItem.classType).listen((event) {
      _fetchOrder();
    });
    _orderList = [];
    _fetchOrder();
  }

 Future _fetchOrder() async {

    List<Map<String, dynamic>> fullOrderItemList = [];

    // fetch all order by user id
    final user = await Amplify.Auth.getCurrentUser();
    List<Order> orderDb = await Amplify.DataStore.query(Order.classType,
        where: Order.USERID.eq(user.userId));

    // fetch order item and user name by order id & user id
    orderDb.asMap().forEach((index, order) async {
      List<Map<String, String>> orderItemByOrderId = [];

      User buyerInfo = (await Amplify.DataStore.query(User.classType,
          where: User.ID.eq(order.userID)))[0];

      List<OrderItem> orderitem = await Amplify.DataStore.query(
          OrderItem.classType,
          where: OrderItem.ORDERID.eq(order.id));

      orderitem.asMap().forEach((index, orderitem) {
        orderItemByOrderId.add({
          "order item id": orderitem.id,
          "item name": orderitem.item,
          "price": orderitem.price.toString(),
          "quantity": orderitem.quantity.toString(),
        });
      });

      fullOrderItemList.add({
        'order id': order.id,
        'order date': order.orderDate,
        'total price': order.totalPrice.toString(),
        'buyer name': buyerInfo.name,
        'buyer phone': buyerInfo.phone,
        'buyer email': buyerInfo.email,
        'order item': orderItemByOrderId,
      });
    });
    setState(() {
      _orderList = fullOrderItemList;
    });
  }
1

There are 1 answers

2
Eric Omine On

You should use await with _fetchOrder().

One way to get around this would be to make _fetchOrder() return the fullOrderItemList and use setState inside Future.then:


  @override
  void initState() {
    super.initState();
    _subscription =
        Amplify.DataStore.observe(OrderItem.classType).listen((event) {
      _fetchOrder().then((orderList) => setState(() {
         _orderList = orderList;
      });
    });
    _orderList = [];
    _fetchOrder().then((orderList) => setState(() {
       _orderList = orderList;
    });
  }

If this doesn't work, you can try this:


_fetchOrder().then((orderList) {
  WidgetsBinding.instance!.addPostFrameCallback((_) => setState(() {
    _orderList = orderList;
  })}
);