1

I'm trying to display a list of images stored in my firebase cloud storage. I have the image name stored in my firestore. and my getURL() function gets the download url as a future for the respective image.

Using future builder I'm successful in displaying the list. I'm trying to achieve the same thing using Obx GetX. The problem is flutter is trying to display the images before the URL is retrieved. How do I successfully return a future of a widget in my second approach

ListView.builder(
                      itemCount: deviceListController.devices[index].images !=
                              null
                          ? deviceListController.devices[index].images!.length
                          : 0,
                      scrollDirection: Axis.horizontal,
                      shrinkWrap: true,
                      itemBuilder: (context, imageIndex) {
                        return SizedBox(
                          height: 100,
                          width: 100,
                          child: FutureBuilder(
                            future:
                                deviceListController.getURL(index, imageIndex),
                            builder: (context, snapshot) {
                              switch (snapshot.connectionState) {
                                case ConnectionState.waiting:
                                  return CircularProgressIndicator();

                                case ConnectionState.done:
                                  return Image.network(deviceListController
                                      .devices[index].imageURL[imageIndex]!);
                                // case ConnectionState.none:

                                // case ConnectionState.active:
                                default:
                                  return Icon(Icons.accessible_forward);
                              }
                            },
                          ),
                        );
                      },
                    ),

here is my attempt at this. the problem is I dont know how to return/implement a future in the obx style.

Obx(
                      () => ListView(
                          scrollDirection: Axis.horizontal,
                          children: deviceListController.devices[index].images!
                              .asMap()
                              .map((ind, image) {
                                deviceListController.getURL(index, ind);
                                return MapEntry(
                                    ind, Image.network(device.imageURL[ind]!));
                              })
                              .values
                              .toList()),
                    ),

Edit: This is closest I could come up with. and it still doesnt load the images. flutter is looking for images before the async task is done.

Obx(() {
                        return deviceListController.devices[index].images !=
                                null
                            ? ListView(
                                scrollDirection: Axis.horizontal,
                                children: deviceListController
                                    .devices[index].images!
                                    .asMap()
                                    .map((ind, image) {
                                      pageState(AppState.loading);
                                      deviceListController.getURL(index, ind);
                                      pageState(AppState.loaded);
                                      return pageState.value == AppState.loading
                                          ? MapEntry(
                                              ind,
                                              Image.network(
                                                  device.imageURL[ind]!))
                                          : MapEntry(
                                              ind, CircularProgressIndicator());
                                    })
                                    .values
                                    .toList())
                            : Spacer();
                      }),
harish balaji
  • 33
  • 1
  • 6

1 Answers1

1

Try using an enum for your state management.

enum AppState { initial, loading, loaded, error, empty, disabled }
Rx<AppState> pageState = AppState.initial.obs;

pageState(AppState.loading);
await some time taking operation.
pageState(AppState.loaded);

Obx(
          () => pageState.value == AppState.loading
              ? Center(child: CircularProgressIndicator())
              : YOUR WIDGET

here, you can use an enum to create state, and show the widgets based on the state ready.

SinaMN75
  • 6,742
  • 5
  • 28
  • 56
  • pls check my edit. I tried to implement what you have showed. i'm still facing some issues. flutter is still accessing the imageurl before the async tasks are done. I think it is mainly cz i am trying to implement it while also mapping a list. lemme know any alternatives that might work in this situation. Thanks :) – harish balaji Sep 22 '21 at 13:17