Rxdart: How to override onAdd or onAddError ?

Created on 27 Jul 2020  路  2Comments  路  Source: ReactiveX/rxdart

I have been trying to do some additional tasks before the error is added and I guess this onAddError () is the way to go but couldn't figure out how.

I can't extend the class because it uses factory constructor
I also tried writing extensions but my ide kept giving me an error. I'm not sure if I have done it correctly either, I don't understand extensions much.

Can you show me some code snippet how it's done?

extension BehaviorExtension on BehaviorSubject {
  void onAddError(error, void Function() callback) {
    callback?.call();
    sink.addError(error);
  }
}

Most helpful comment

extension method act as a static helper method with syntactic sugar, it cannot have a same name as method in class.
You can inherit Subject class and delegate implementation by a BehaviorSubject:

import 'package:rxdart/rxdart.dart';

void main() async {
  var s = BehaviorSubjectWithOnErrorCallback<int>.seeded(
    3,
    callback: () => print('before add error'),
  );
  s.stream.listen(print, onError: print);
  s.add(1);
  s.addError(Exception());
  s.addError(Exception());
}

class BehaviorSubjectWithOnErrorCallback<T> extends Subject<T>
    implements ValueStream<T> {
  final void Function() _callback;
  final BehaviorSubject<T> _subject;

  factory BehaviorSubjectWithOnErrorCallback({
    void Function() callback,
    void Function() onListen,
    void Function() onCancel,
    bool sync = false,
  }) {
    return BehaviorSubjectWithOnErrorCallback._(callback,
        BehaviorSubject<T>(onListen: onListen, onCancel: onCancel, sync: sync));
  }

  factory BehaviorSubjectWithOnErrorCallback.seeded(
    T value, {
    void Function() callback,
    void Function() onListen,
    void Function() onCancel,
    bool sync = false,
  }) {
    return BehaviorSubjectWithOnErrorCallback._(
        callback,
        BehaviorSubject<T>.seeded(value,
            onListen: onListen, onCancel: onCancel, sync: sync));
  }

  BehaviorSubjectWithOnErrorCallback._(this._callback, this._subject)
      : super(_subject, _subject);

  @override
  void onAddError(Object error, [StackTrace stackTrace]) => _callback?.call();

  @override
  Object get error => _subject.error;

  @override
  bool get hasError => _subject.hasError;

  @override
  bool get hasValue => _subject.hasValue;

  @override
  T get value => _subject.value;
}

All 2 comments

extension method act as a static helper method with syntactic sugar, it cannot have a same name as method in class.
You can inherit Subject class and delegate implementation by a BehaviorSubject:

import 'package:rxdart/rxdart.dart';

void main() async {
  var s = BehaviorSubjectWithOnErrorCallback<int>.seeded(
    3,
    callback: () => print('before add error'),
  );
  s.stream.listen(print, onError: print);
  s.add(1);
  s.addError(Exception());
  s.addError(Exception());
}

class BehaviorSubjectWithOnErrorCallback<T> extends Subject<T>
    implements ValueStream<T> {
  final void Function() _callback;
  final BehaviorSubject<T> _subject;

  factory BehaviorSubjectWithOnErrorCallback({
    void Function() callback,
    void Function() onListen,
    void Function() onCancel,
    bool sync = false,
  }) {
    return BehaviorSubjectWithOnErrorCallback._(callback,
        BehaviorSubject<T>(onListen: onListen, onCancel: onCancel, sync: sync));
  }

  factory BehaviorSubjectWithOnErrorCallback.seeded(
    T value, {
    void Function() callback,
    void Function() onListen,
    void Function() onCancel,
    bool sync = false,
  }) {
    return BehaviorSubjectWithOnErrorCallback._(
        callback,
        BehaviorSubject<T>.seeded(value,
            onListen: onListen, onCancel: onCancel, sync: sync));
  }

  BehaviorSubjectWithOnErrorCallback._(this._callback, this._subject)
      : super(_subject, _subject);

  @override
  void onAddError(Object error, [StackTrace stackTrace]) => _callback?.call();

  @override
  Object get error => _subject.error;

  @override
  bool get hasError => _subject.hasError;

  @override
  bool get hasValue => _subject.hasValue;

  @override
  T get value => _subject.value;
}

Thank you very helpful

Was this page helpful?
0 / 5 - 0 ratings