asyncNotifierPod<N extends AsyncNotifier<T>, T> function

PodNotifier<Pod<N>, AsyncValue<T>> asyncNotifierPod<N extends AsyncNotifier<T>, T>(
  1. N create()
)

A pod which creates and listen to an AsyncNotifier.

This is similar to futurePod but allows to perform side-effects.

The syntax for using this pod is slightly different from the others in that the pod's function doesn't receive a "ref". Instead the ref are directly accessible in the associated AsyncNotifier.

Implementation

PodNotifier<Pod<N>, AsyncValue<T>>
    asyncNotifierPod<N extends AsyncNotifier<T>, T>(
  N Function() create,
) {
  var isPodDisposed = false;
  final podNotifier = pod<N>((ref) {
    final notifier = create().._ref = ref;

    var disposed = false;
    ref.onDispose(() => disposed = true);

    notifier.state = const AsyncLoading();

    final result = notifier.build();

    if (result is Future<T>) {
      result.then(
        (value) {
          if (disposed) return;
          notifier.state = AsyncValue.data(value);
        },
        onError: (Object error, StackTrace stackTrace) {
          if (disposed) return;
          notifier.state = AsyncValue.error(error, stackTrace);
        },
      );
    } else {
      notifier.state = AsyncValue.data(result);
    }

    return notifier;
  });

  return internalPodNotifier<Pod<N>, AsyncValue<T>>(podNotifier, (ref, pod) {
    final notifier = ref.watch(pod);

    if (isPodDisposed) {
      var disposed = false;
      ref.onDispose(() => disposed = true);

      notifier.state = const AsyncLoading();

      final result = notifier.build();

      if (result is Future<T>) {
        result.then(
          (value) {
            if (disposed) return;
            notifier.state = AsyncValue.data(value);
          },
          onError: (Object error, StackTrace stackTrace) {
            if (disposed) return;
            notifier.state = AsyncValue.error(error, stackTrace);
          },
        );
      } else {
        notifier.state = AsyncValue.data(result);
      }
    }

    final removeListener = notifier.addListener((state) {
      ref.setSelf(state);
    });

    ref.onDispose(() {
      isPodDisposed = true;
      removeListener();
    });

    return notifier.state;
  });
}