NULL Accumulator on ScanStreamTransformer

Issue

I am implementing an api that requires recursive calls to get all data. I have implemented a Bloc component that has a recursive transformer. However, it seems the transformer is keeps returning a null accumulator on the recursive call.

comments_bloc.dart

class CommentsBloc {
  final _repository = Repository();
  final _commentsFetcher = PublishSubject<int>();
  final _commentsOutput = BehaviorSubject<Map<int, Future<ItemModel>>>();

  // Stream Getters
  Observable<Map<int, Future<ItemModel>>> get itemWithComments =>
      _commentsOutput.stream;

  // Sink getters
  Function(int) get fetchItemWithComments => _commentsFetcher.sink.add;

  CommentsBloc() {
    _commentsFetcher.stream
        .transform(_commentsTransformer())
        .pipe(_commentsOutput);
  }

  _commentsTransformer() {
    return ScanStreamTransformer<int, Map<int, Future<ItemModel>>>(
      (cache, int id, index) {
        cache[id] = _repository.fetchItem(id);
        cache[id].then((ItemModel item) {
          item.kids.forEach((kidId) => fetchItemWithComments(kidId));
        });
      },
      <int, Future<ItemModel>>{},
    );
  }

  dispose() {
    _commentsFetcher.close();
    _commentsOutput.close();
  }
}

app.dart

return MaterialPageRoute(
  builder: (BuildContext context) {
    final itemId = int.parse(settings.name.replaceFirst('/', ''));
    final commentsBloc = CommentsProvider.of(context);

    commentsBloc.fetchItemWithComments(itemId);

    return NewsDetail(itemId: itemId);
  },
  );

Error

E/flutter (17142): [ERROR:flutter/shell/common/shell.cc(178)] Dart Error: Unhandled exception:
E/flutter (17142): NoSuchMethodError: The method '[]=' was called on null.
E/flutter (17142): Receiver: null
E/flutter (17142): Tried calling: []=(19307509, Instance of 'Future<ItemModel>')
E/flutter (17142): #0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:1112:29)
E/flutter (17142): #1      _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (17142): #2      _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)

The _commentsTransformer executes only the first instance the throws the error on cache[id] = _repository.fetchItem(id);
;

Solution

Apparently cache is null. It is because you didn’t return cache inside the transformer’s accumulator function. You need to return it since it not an arrow function.

  _commentsTransformer() {
    return ScanStreamTransformer<int, Map<int, Future<ItemModel>>>(
      (cache, int id, index) {
        cache[id] = _repository.fetchItem(id);
        cache[id].then((ItemModel item) {
          item.kids.forEach((kidId) => fetchItemWithComments(kidId));
        });
        return cache;    //  <-- code fix here.
      },
      <int, Future<ItemModel>>{},
    );
  }

Answered By – Amsakanna

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *