diff --git a/packages/provider/lib/src/async_provider.dart b/packages/provider/lib/src/async_provider.dart index b640ab752..c6103fe04 100644 --- a/packages/provider/lib/src/async_provider.dart +++ b/packages/provider/lib/src/async_provider.dart @@ -181,10 +181,15 @@ class FutureProvider extends DeferredInheritedProvider?, T> { /// Creates a [Future] from `create` and subscribes to it. /// /// `create` must not be `null`. + /// + /// The optional [dispose] callback is invoked with the last exposed value + /// when the provider is removed from the widget tree, allowing cleanup of + /// resources (closing streams, cancelling timers, etc.). FutureProvider({ Key? key, required Create?> create, required T initialData, + Dispose? dispose, ErrorBuilder? catchError, UpdateShouldNotify? updateShouldNotify, bool? lazy, @@ -195,6 +200,7 @@ class FutureProvider extends DeferredInheritedProvider?, T> { lazy: lazy, builder: builder, create: create, + dispose: dispose, updateShouldNotify: updateShouldNotify, startListening: _futureStartListening( catchError: catchError, diff --git a/packages/provider/lib/src/deferred_inherited_provider.dart b/packages/provider/lib/src/deferred_inherited_provider.dart index 10dcad321..76d533c73 100644 --- a/packages/provider/lib/src/deferred_inherited_provider.dart +++ b/packages/provider/lib/src/deferred_inherited_provider.dart @@ -35,7 +35,7 @@ class DeferredInheritedProvider extends InheritedProvider { DeferredInheritedProvider({ Key? key, required Create create, - Dispose? dispose, + Dispose? dispose, required DeferredStartListening startListening, UpdateShouldNotify? updateShouldNotify, bool? lazy, @@ -165,7 +165,7 @@ class _CreateDeferredInheritedProvider extends _DeferredDelegate { }) : super(updateShouldNotify, startListening); final Create create; - final Dispose? dispose; + final Dispose? dispose; @override _CreateDeferredInheritedProviderElement createState() { @@ -220,7 +220,13 @@ class _CreateDeferredInheritedProviderElement void dispose() { super.dispose(); if (_didBuild) { - delegate.dispose?.call(element!, _controller as T); + if (T is Future) { + (_controller as Future).then((value) => delegate.dispose?.call(element!, value)); + } else if (isLoaded) { + delegate.dispose?.call(element!, value); + } else { + delegate.dispose?.call(element!, _controller as R); + } } }