Huzzi
Huzzi

Reputation: 571

rxdart filter return a single item from stream

How can I filter a stream? I want to get one record where the uid matches. The return item must a be a stream.

import 'dart:async';
import 'package:demo/models/profile.dart';
import 'package:demo/services/database/database.dart';
import 'package:rxdart/rxdart.dart';
import 'bloc_provider.dart';

class SearchResultsBloc implements BlocBase {
  SearchResultsBloc() {
    DatabaseService().Search().listen((data) => _inList.add(data));
  }

  final _listController = BehaviorSubject<List<Profile>>();
  Stream<List<Profile>> get outList => _listController.stream;
  Sink<List<Profile>> get _inList => _listController.sink;

  final _detailsController = BehaviorSubject<Profile>();
  
  Stream<Profile> outDetails(String uid) {
   // return single item  from outList where uid matches.
  }

  @override
  void dispose() {
    _listController.close();
    _detailsController.close();
  }
}

Upvotes: 1

Views: 999

Answers (1)

matehat
matehat

Reputation: 5374

Something like that should work:

  Stream<Profile> outDetails(String uid) {
    return outList.map<Profile>((results) => 
      results.firstWhere((profile) => profile.uid == uid)
    );
  }

Basically, you're mapping your stream of lists of profiles to a stream of profiles, where, for each list of profiles, you're returning the first (possibly null) profile that matched the argument.

P.S. Don't forget to manage the returned stream properly on the caller side.


EDIT: if it's possible that no profile be found for a given uid, you should add the orElse: argument:

results.firstWhere(
  (profile) => profile.uid == uid,
  orElse: () => null
)

This will make sure StateError doesn't get thrown, in case returning null is the right thing to do for you.

Upvotes: 4

Related Questions