ben
ben

Reputation: 173

How to override a NotifierProvider in riverpod

I've been unable to find any information on how to properly override a Notifier using Riverpod (no code-gen). From the documentation, the build method returns an empty list of Todo, however what if we want to override it with a intial list (synchrounously)?

Given something like:

final todosProvider = NotifierProvider<TodosNotifier, List<Todo>>(() {
  return TodosNotifier();
});

I would assume you would override

ProviderScope(
                overrides: [
                  todosProvider.overrideWith((ref) => TodosNotifier(defaultList)),
                ],

However the Notifier class, e.g.

class TodosNotifier extends Notifier<List<Todo>> {
  // We initialize the list of todos to an empty list
  @override
  List<Todo> build() {
    return [];
  }

has no clear way to accept a parameter into the constructor (and hence the build method).

Is this by design, or am I missing something? Ï

Upvotes: 2

Views: 524

Answers (2)

ben
ben

Reputation: 173

The answer, which was there all along, is to simply listen to providers within the build method.

@override
  List<Todo> build() {
    final initalList = ref.watch(initialListProvider);
    // Alternatively, if async: = await ref.watch(streamProvider.future);
    final filters = ref.watch(filtersProvider);
    return _defaultList ?? [];
  }

We can then override the intialListProvider and filtersProvider at the closest ProviderScope. Thanks for the help

Upvotes: 1

Ruble
Ruble

Reputation: 4844

Purely hypothetically, you could do something like this:

import 'package:flutter_riverpod/flutter_riverpod.dart';

class Todo {}

final todosProvider =
    NotifierProvider<TodosNotifier, List<Todo>>(TodosNotifier.new);

class TodosNotifier extends Notifier<List<Todo>> {
  TodosNotifier([this._defaultList]);

  List<Todo>? _defaultList;

  @override
  List<Todo> build() {
    return _defaultList ?? [];
  }
}

void main() {
  final defaultList = [Todo()];

  ProviderScope(
    child: ...,
    overrides: [
      todosProvider.overrideWith(() => TodosNotifier(defaultList)),
    ],
  );
}

But it's worth considering using a more complex (sealed) state in the notifier instead.

Upvotes: 0

Related Questions