Search code examples
flutterrxdart

Different type error when trying to access BLoC data in StreamBuilder


I'm trying to implementing Bloc on Flutter and i just learn about this feature and i get error:

Error:

Another exception was thrown: type 'Future' is not a subtype of type 'Stream'

my server return this structure and i want to get that with bloc and rxDart, for example:

[
    "active"=> 1,
    "name"=> "MY NAME",
    "avatar"=> "http://www.sample.com/avatar.png",
    ...
]

my implemented Repository class :

class Repository {
  final userInformation = InstagramApiProviders();

  Future<UserInfo> userInfo() => userInformation.checkUserLogin();
}

LoginBlock class

class LoginBlock{
  final _repository = Repository();
  final _login_fetcher = PublishSubject<UserInfo>();

  Observable<UserInfo> get login=>_login_fetcher.stream;

  fetchLogin() async{
    UserInfo userInfo = await _repository.userInfo();
    _login_fetcher.sink.add(userInfo);
  }

  dispose(){
    _login_fetcher.close();
  }
}

final bloc = LoginBlock();

click on button on view implementation:

onPressed: () {
  setState(() {
    if (_checkLoginInstagram()) {
      StreamBuilder(
        stream: bloc.fetchLogin(),
        builder: (context,
            AsyncSnapshot<UserInfo>
            snapshot) {
          if (snapshot.hasData) {
            parseResponse(snapshot);
          }
        },
      );
    }
  });
},

parseResponse method:

void parseResponse(AsyncSnapshot<UserInfo> snapshot) {
  debugPrint(snapshot.data.avatar);
}

Solution

  • You are providing a Future object instead a stream to stream property of your StreamBuilder.

    //...
    StreamBuilder(
            stream: bloc.fetchLogin(), // THIS LINE IS WRONG
    

    As your fetchLogin is an async function by default async methods returns always a Future object in your case Future<void>. You should replace the wrong line by:

     //...
        StreamBuilder(
                stream: bloc.login,
    

    And make fetchLogin() call in onPress callback and you don't need setState calls. I cant get it why you have a setState call there...