0

I want to return a list of members via a StreamController.

batches collection contains batch details and ids of members assigned to the batch.

So, in-order to get the list of members in a batch, have to loop through batch collection and get the ids of members, then match with members collection and return the matching member data as stream.

  final CollectionReference _batchCollectionReference =
      Firestore.instance.collection('batches');
  final CollectionReference _membersCollectionReference =
      Firestore.instance.collection('members');

  final StreamController<List<Member>> _membersController =
      StreamController<List<Member>>.broadcast();

  Stream getMembers(String batchId) { //passing a batch id
    _batchCollectionReference
        .document(batchId)
        .snapshots()
        .map((batchSnapshot) => Batch.fromData( //return as Batch type
            data: batchSnapshot.data, batchId: batchSnapshot.documentID))
        .listen((snapshot) {

      List<String> members = snapshot.members; //list of members

      members.forEach((member) {
        var data = _membersCollectionReference
            .document(member)
            .snapshots()
            .map((memberData) => Member.fromData(data: memberData.data)); //return as Member type

        _membersController.add(data);
      });
    });

    return _membersController.stream;
  }
}

The problem is I couldn't able to push the member data to the StreamContoller.

It says,

The argument type 'Stream<Member>' can't be assigned to the parameter type 'List<Member>'

The stream should contains instance of members; Ex: [[instance of 'Member'], [instance of 'Member'], [instance of 'Member']]

If I got the data like this way, it would be easy to loop and do the other stuff.

I couldn't able fix this issue. Any help would be appreciated.

2
  • you dont need StreamContoller (and Stream.listen()) at all: just use Stream API like map / asyncMAp / expand (or the most generic transform) etc Commented May 19, 2020 at 16:15
  • can you provide any examples? or do you have any video tutorial? Commented May 19, 2020 at 16:19

1 Answer 1

1

Firstable when you need to add a list to the stream so convert your map data to a list, just adding toList() at the end of you map as follows:

members.forEach((member) {
        var data = _membersCollectionReference
            .document(member)
            .snapshots()
            .map((memberData) => Member.fromData(data: memberData.data)).toList();

And to push the data in the Stream, you need to use sink.add() this can be an example of a function to push data into the stream and the other one to get the values:

final StreamController<List<Member>> _membersController = StreamController<List<Member>>.broadcast();

  /// Inputs
  Function(List<Member>) get changeMembers => _membersController.sink.add;

  /// Getters
  String get members => _membersController.value;

In your case you can do it directly in this way:

_membersController.sink.add(data);

Hope it helps, for more info please check this video or the documentation about streams in dart.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the quick response. I updated my code as per your suggestion. But now I'm getting this error . The argument type 'Stream<Member>' can't be assigned to the parameter type 'List<Member>'. What should I do?
I updated the StreamController<List<Member>> to StreamController<Stream<Member>> then it worked. Thanks dude.
You can also return stream from the StreamController. StreamController<Stream<List<Member>>>.stream

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.