티스토리 뷰

ISSUE :  CustomScrollView widget which consists of SlivderList(SliverChildBuilderDelegate) and is supported by riverpod state management suddenly occured the error below. Sliver-related widget doesn't show the specified widget from provider's when method (error: (err, stackTrace) => const SizedBox()) and throws an exception

 

Error Output

Code: 

list() {
    final notifications = ref.watch(notificationProvider);

    return Expanded(
      child: NotificationListener<ScrollEndNotification>(
        child: Scrollbar(
          thickness: 0,
          child: RefreshIndicator(
            onRefresh: () async {
              ref.read(notificationProvider.notifier).getList();
            },
            child: CustomScrollView(
              shrinkWrap: true,
              restorationId: 'notifications',
              slivers: <Widget>[
                notifications.when(data: (data) {
                  context.loaderOverlay.hide();
                  return SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (ctx, idx) => _push(notification: data[idx]),
                      childCount: data.length,
                    ),
                  );
                }, loading: () {
                  context.loaderOverlay.show(widget: const Spinner());
                  return const SizedBox();
                }, error: (err, stackTrace) {
                  if (notifications.hasValue) {
                    return SliverList(
                      delegate: SliverChildBuilderDelegate(
                        (ctx, idx) =>
                            _push(notification: notifications.value![idx]),
                        childCount: notifications.value!.length,
                      ),
                    );
                  }
                  return const SizedBox();
                }),
                LazyLoadingBottom(asyncValue: notifications),
              ],
            ),
          ),
        ),
      ),
    );
  }

 

 

Solution 1 -> Add an additional condition if the data is empty. (Failed)

 notifications.when(data: (data) {
                  context.loaderOverlay.hide();
                  if (data.isNotEmpty) {
                    return SliverList(
                      delegate: SliverChildBuilderDelegate(
                        (ctx, idx) => _push(notification: data[idx]),
                        childCount: data.length,
                      ),
                    );
                  } else {
                    return const SizedBox();
                  }

Solution 2 -> Check if the data object field name has changed. (applicable partly)

ex) NotificationModel => topicType json key has changed from "msg_notice" to "msgNotice".

Solution 3 -> Reorder widget tree. NotificationListener should be inside "data" instead of putting list provider when method INSIDE "NotificationListener" to avoid errors. 

Expanded(
              child: notifications.when(
                data: (data) {
                  if (data.isNotEmpty) {
                    return NotificationListener<ScrollEndNotification>(
                      child: Scrollbar(
                        thickness: 0,
                        child: RefreshIndicator(
                          onRefresh: () async {
                            ref
                                .refresh(notificationProvider.notifier)
                                .getList();
                          },
                          child: CustomScrollView(
                            shrinkWrap: true,
                            restorationId: 'notifications',
                           slivers: <Widget>[
                              SliverList(
                                delegate: SliverChildBuilderDelegate(
                                  (ctx, idx) => _push(notification: data[idx]),
                                  childCount: data.length,
                                ),
                              ),
                              LazyLoadingBottom(asyncValue: notifications),
                            ],
                          ),
                        ),
                      ),
                    );
                  } else {
                    return const SizedBox();
                  }
                },
                loading: () => const Spinner(),
                error: (error, stackTrace) => const SizedBox(),
              ),
            ),