5

I am trying to create a download functionality which downloads files from url in to phone storage and i made a widget to display if the download starts and also the progress counter to be displayed using getx obs

final ApiServiceController uController = Get.put(ApiServiceController());

downloading(String fileUrl, String fileName) async {
    Dio dio = Dio();
    fToast("Downloading... $fileName", pop);

    try {
      var dir = await downloadDirectory();
      uController.isDwd.value = true;

      await dio.download(fileUrl, "${dir.path}/$fileName",
          onReceiveProgress: (rec, total) {
        print("Rec: $rec , Total: $total");

        uController.dwdP.value = ((rec / total) * 100).toStringAsFixed(0) + "%";
      });
      fToast("Downloaded", pop);
    } catch (e) {
      print(e);
    }
    uController.isDwd.value = false;

    print("Download completed");
  }

Widget to display

Stack(children: [
///.. Container widget here,
Obx(() {
    return uController.isDwd.value
        ? loading(context, uController.dwdP.value)
        : SizedBox(height: 0);
  })
])

but whenever i click the download button to start download it throws the error

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Obx(has builder, dirty, state: _ObxState#291e4):
visitChildElements() called during build.

The BuildContext.visitChildElements() method can't be called during build because the child list is still being updated at that point, so the children might not be constructed yet, or might be old children that are going to be replaced.
The relevant error-causing widget was
Obx

And the error displays on the screen until the download is done. I saw that using this will fix it

WidgetsBinding.instance.addPostFrameCallback((_) {
      // executes after build
});

but i don't know how to use it in this case. Please is there a way to fix this and if you need more explanation or info please tell me

Brightcode
  • 660
  • 9
  • 27

4 Answers4

1

in my case I was changing observable variable 2 times by mistake on the controller on ReadyMethod & inside the widget build method

Abdelrahman Tareq
  • 1,874
  • 3
  • 17
  • 32
1

I think this problem is caused by using a obs variable inside a sub widget which It's parent widget also includes same or somehow the same obs variable or there is a State operation in the sub widget which is related to parent widget's . You'd better provide more UI code in order to make the clear the child widgets details , But my guess is that you are doing some operation with the context that you gave to loading widget and that operation causes the UI build and change in the context , if not please provide more detailed code .

1

In my case, I was changing the observable variable 2 times by mistake one in the on select & inside the widget build method.

Then I commented on one of them and it started working.

This may also work for you .....try it.

Thanks.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Sumit Sharma May 28 '22 at 17:03
0

Your code looks fine to me. I think you should create a issue on GetX on GitHub.

Sangam
  • 317
  • 2
  • 7