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);
;
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>>{},
);
}