0

Here i am using obx to display an obs variable, at first the error didn't show up, but when i did hot restart, it show this error.

Unhandled Exception: setState() or markNeedsBuild() called during build. This Obx widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase. The widget on which setState() or markNeedsBuild() was called was: Obx

class CheckoutScreen extends StatelessWidget {
  const CheckoutScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var detailHotelController = Get.put(DetailHotelController());
    var homeController = Get.put(HomeController());
    var userDataFormController = Get.put(UserDataFormController());
    var checkoutController = Get.put(CheckoutController());
    var bookingController = Get.put(BookingController());
    var authController = Get.put(AuthController());
    final orientation = MediaQuery.of(context).orientation;
    detailHotelController.getDetailHotel(userDataFormController.hotelId.value);
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        toolbarHeight: 20.w,
        title: Image.asset(
          "assets/turu.png",
          height: 10.h,
        ),
        elevation: 0,
        backgroundColor: Colors.white10,
      ),
      body: Padding(
        padding: const EdgeInsets.only(bottom: 16.0),
        child: SingleChildScrollView(
          child: Obx(
            () => (detailHotelController.isLoading.value)
                ? Center(
                    child: LoadingAnimationWidget.waveDots(
                        color: const Color(0xffF0B900), size: 50))
                : Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            "Tinjau Pemesanan",
                            style: TextStyle(
                                fontSize: 14.sp,
                                color: const Color(0xffF0B900),
                                fontWeight: FontWeight.bold),
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 1.sp,
                            ),
                          ),
                          Text(
                            detailHotelController.detailHotel.value.hotel!.name,
                            style: TextStyle(
                                fontSize: 13.sp, fontWeight: FontWeight.bold),
                          ),
                          const SizedBox(
                            height: 12,
                          ),
                          Text(
                            detailHotelController
                                .detailHotel.value.hotel!.address
                                .replaceAll("\n", " "),
                            style: TextStyle(fontSize: 10.sp),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisSize: MainAxisSize.max,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    "Check-In",
                                    style: TextStyle(
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                  Text(
                                      homeController
                                          .checkInController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                              SizedBox(
                                width: 16.w,
                              ),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text("Check-Out",
                                      style: TextStyle(
                                          fontSize: 10.sp,
                                          fontWeight: FontWeight.bold)),
                                  Text(
                                      homeController
                                          .checkOutController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                            ],
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Text(
                              "Detail Pesanan",
                              style: TextStyle(
                                  fontSize: 12.sp, fontWeight: FontWeight.bold),
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Subtotal",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                  RupiahUtils.beRupiah(
                                      userDataFormController.subtotal.value),
                                  style: TextStyle(fontSize: 12.sp))
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            children: [
                              Expanded(
                                  child: CustomTextField(
                                label: "Masukkan Kode Promo",
                                errorText: "",
                                controller: checkoutController.promoController.value,
                                isPasswordField: false,
                                isRequired: false,
                              )),
                              Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: ElevatedButton(
                                    style: ElevatedButton.styleFrom(
                                        primary: const Color(0xffF0B900)),
                                    onPressed: () => checkoutController.checkPromo(checkoutController.promoController.value.text, userDataFormController.subtotal.value.toString()),
                                    child: checkoutController.isLoading.value ? LoadingAnimationWidget.twoRotatingArc(color: Colors.white, size: 20) : const Text("Terapkan",)),
                              )
                            ],
                          ),
                          Visibility(visible: checkoutController.isVisible.value, child: Text(checkoutController.placeholderCheckPromo.value, style: TextStyle(color: checkoutController.textColor.value))),
                          SizedBox(
                            width: orientation == Orientation.landscape ? 100.h : 100.w,
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                  primary: Colors.white,
                                  side: const BorderSide(
                                      width: 1.0, color: Color(0xffF0B900))),
                              onPressed: () {
                                Get.to(() => const PromoList());
                              },
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Text(
                                  "Lihat Daftar Promo",
                                  style: TextStyle(
                                      color: const Color(0xffF0B900),
                                      fontSize: 10.sp,
                                      fontWeight: FontWeight.bold),
                                ),
                              ),
                            ),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Promo Diskon",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? "-Rp 0" : RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value),
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Cashback",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value) : "-Rp 0",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Total",
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                              Text(
                                RupiahUtils.beRupiah(checkoutController.total.value),
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                            ],
                          ),
                          Padding(
                            padding:
                                const EdgeInsets.only(top: 16.0, bottom: 8.0),
                            child: SizedBox(
                              width: orientation == Orientation.landscape
                                  ? 100.h
                                  : 100.w,
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  primary: const Color(0xffF0B900),
                                ),
                                onPressed: () {
                                  bookingController.postBooking(
                                    context, 
                                    authController.userToken.value, 
                                    detailHotelController.detailHotel.value.hotel!.id, 
                                    homeController.checkInController.value.text, 
                                    homeController.checkOutController.value.text, 
                                    checkoutController.total.value.toString(), 
                                    checkoutController.promoController.value.text, 
                                    userDataFormController.detailBooking
                                  );
                                },
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Text(
                                    "Proses Booking",
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ]),
                  ),
          ),
        ),
      ),
    );
  }
}

Can someone help me to identify what's wrong with my code?

David Scholz
  • 8,421
  • 12
  • 19
  • 34

1 Answers1

0

detailHotelController.getDetailHotel(userDataFormController.hotelId.value); This line is causing the problem.

Instead of calling this method from the build method, you should call it from one of the lifecycle method of the GetxController. onInit() is a good place.

What's wrong?

The Obx widget is like a chunk of StatefulWidget which is like calling the setState() method every time the watched observable changes. But when you hot reload, the above controller method is called (because hot reload calls the build method and then the above method also gets called) causing the observable to change thus triggering rebuild in the middle of a build.

S. M. JAHANGIR
  • 4,324
  • 1
  • 10
  • 30