'Read a provider inside a FutureProvider

When we need to read (not watch) a provider inside another one the documentation is clear:

"DON'T CALL READ INSIDE THE BODY OF A PROVIDER"

final myProvider = Provider((ref) {
  // Bad practice to call `read` here
  final value = ref.read(anotherProvider);
});

And it suggest to pass to the value exposed the Reader function: https://riverpod.dev/docs/concepts/combining_providers#can-i-read-a-provider-without-listening-to-it

final userTokenProvider = StateProvider<String>((ref) => null);

final repositoryProvider = Provider((ref) => Repository(ref.read));

class Repository {
  Repository(this.read);

  /// The `ref.read` function
  final Reader read;

  Future<Catalog> fetchCatalog() async {
    String token = read(userTokenProvider);

    final response = await dio.get('/path', queryParameters: {
      'token': token,
    });

    return Catalog.fromJson(response.data);
  }
}

And that's ok, but what is the best practice when I need to read a provider inside a FutureProvider? I find myself in this situation many time because I expose the api as providers and inside the FutureProvider I call watch to get the api I need. But I noticed that, because I'm watching the Api provider inside the userProvider, this won't gets disposed after been used.

Here's an example of what I'm trying to say:

API CLASS

final userApiProvider = Provider((ref) => UserApi(ref.read));
class UserApi {

  final Dio _dio;

 const UserApi(Reader read): 
   _dio = read(dioProvider);

  Future<Response> getUser(String id, { CancelToken? cancelToken }) async{
    final _url = '$URL_TO_API/$id';
    return _dio.get(_url, cancelToken: cancelToken);
  }

}

When using the API inside a FutureProvider

final userProvider = FutureProvider.autoDispose.family<User, int>((ref, userId) async {
  final userApi = **ref.watch(userApi);**
  final cancelToken = CancelToken();
  ref.onDispose(() { cancelToken.cancel(); });

  final user = await userApi.getUser(cancelToken: cancelToken);
  return user;
});


Solution 1:[1]

The same logic applies.

By "Don't use read inside a provider", it isn't talking about the class Provider specifically, but any provider – so FutureProvider included.

In general, you should avoid using read as much as possible.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rémi Rousselet