watchAllNotifier method

  1. @protected
DataStateNotifier<List<T>> watchAllNotifier({
  1. bool? remote,
  2. Map<String, dynamic>? params,
  3. Map<String, String>? headers,
  4. bool? syncLocal,
  5. String? finder,
  6. DataRequestLabel? label,
})
inherited

Implementation

@protected
DataStateNotifier<List<T>> watchAllNotifier({
  bool? remote,
  Map<String, dynamic>? params,
  Map<String, String>? headers,
  bool? syncLocal,
  String? finder,
  DataRequestLabel? label,
}) {
  remote ??= _remote;
  syncLocal ??= false;

  final maybeFinder = _internalHolder?.finders[finder]?.call(this);
  final finderFn = maybeFinder is DataFinderAll<T> ? maybeFinder : findAll;

  // we can't use `findAll`'s default internal label
  // because we need a label to handle events
  label ??= DataRequestLabel('watchAll', type: internalType);

  log(label, 'initializing');

  // closure to get latest models
  List<T> _getUpdatedModels() {
    return localAdapter.findAll();
  }

  final notifier = DataStateNotifier<List<T>>(
    data: DataState(_getUpdatedModels(), isLoading: remote!),
  );

  notifier._reloadFn = () async {
    if (!notifier.mounted) {
      return;
    }

    if (remote!) {
      notifier.updateWith(isLoading: true);
    }

    await finderFn(
      remote: remote,
      params: params,
      headers: headers,
      syncLocal: syncLocal,
      label: label,
      onError: (e, label, _) async {
        try {
          await onError<List<T>>(e, label);
        } on DataException catch (err) {
          e = err;
        } catch (_) {
          rethrow;
        }
        if (notifier.mounted) {
          notifier.updateWith(isLoading: false, exception: e);
        }
        return [];
      },
    );
    if (remote) {
      // trigger doneLoading to ensure state is updated with isLoading=false
      graph._notify([label.toString()], type: DataGraphEventType.doneLoading);
    }
  };

  // kick off
  notifier.reload();

  final throttleDuration = ref.read(graphNotifierThrottleDurationProvider);
  final throttledGraph = graph.throttle(() => throttleDuration);

  final states = <DataState<List<T>>>[];

  final dispose = throttledGraph.addListener((events) {
    if (!notifier.mounted) {
      return;
    }

    for (final event in events) {
      // handle done loading
      if (notifier.data.isLoading &&
          event.keys.last == label.toString() &&
          event.type == DataGraphEventType.doneLoading) {
        final models = _getUpdatedModels();
        states.add(DataState(models, isLoading: false, exception: null));
      }

      if (notifier.data.isLoading == false &&
          event.type.isNode &&
          event.keys.first.startsWith(internalType)) {
        final models = _getUpdatedModels();
        log(label!, 'updated models', logLevel: 2);
        states.add(DataState(
          models,
          isLoading: notifier.data.isLoading,
          exception: notifier.data.exception,
          stackTrace: notifier.data.stackTrace,
        ));
      }

      if (event.type == DataGraphEventType.clear &&
          event.keys.first.startsWith(internalType)) {
        log(label!, 'clear local storage', logLevel: 2);
        states.add(DataState([], isLoading: false, exception: null));
      }
    }

    _updateFromStates(states, notifier);
  });

  notifier.onDispose = () {
    log(label!, 'disposing');
    dispose();
  };
  return notifier;
}