0

I put together a sample app that implements an username and password field using streams with verification using validation transforms. I used RxDart for this and I hooked up the "Login" button to enable/disable based on 2 streams results being true.

bloc.dart

  Stream<bool> get submitValidWithCombineLatestStream =>
  CombineLatestStream([email, password], (list) => true);

login_page.dart

 Widget submitButton(Bloc bloc) {
 return StreamBuilder(
   stream: bloc.submitValidWithCombineLatestStream,
   builder: (_, snapshot) {
    return RaisedButton(
      color: Colors.deepPurpleAccent,
      child: Text(
        'Submit',
        style: TextStyle(color: Colors.white),
      ),
      onPressed: !snapshot.hasData ? null : bloc.submit,
    );
  },
 );
}

I have coded the same sample app using flutter_bloc but I'm trying to figure out how to enable/disable the "Login" button using whatever bloc has for CombineLatestStream. Does anyone know how to do this?

I realize that this is total overkill but I'm trying to figure this out using this simple example and I'm not sure how to access all the cool RxDart functionality once you convert to bloc (flutter_bloc). I'd like to have the best of both worlds WITHOUT importing/using RxDart.

Is that possible?

An example of what I’m looking for would be:

  • I’m building a form that requires 3 different backend calls. I’d prefer to show the progress indicator while all 3 calls are working and block until all 3 calls return. I’d like to do that via CombineLatestStreams since all 3 return Steam Futures.
JustLearningAgain
  • 2,227
  • 4
  • 34
  • 50

2 Answers2

0

Problem in your main bloc class,check out this github code, https://github.com/hoc081098/flutter_validation_login_form_BLoC_pattern_RxDart

In short like this,you can use CombineLatestStream you can set in your main bloc class like this,

return LoginBloc._(
      emailChanged: emailS.add,
      passwordChanged: passwordS.add,
      submitLogin: () => submitLoginS.add(null),
      emailError$: emailError$,
      passwordError$: passwordError$,
      isLoading$: isLoadingS.stream,
      message$: message$,
      dispose: DisposeBag([...subjects, message$.connect()]).dispose,
    ); 
Shirsh Shukla
  • 5,491
  • 3
  • 31
  • 44
  • I was able to see successfully code a solution using RxDart. What I’m trying to do is solve the problem using the flutter_bloc package. I’m sure there is a way to do it but I haven’t been able to figure it out. Before me and my team commit we need to know if the bloc package can do more complex operations. – JustLearningAgain Dec 22 '20 at 18:03
  • You are not added sufficient code to understand mistake,that's why I shre you code that have same functionality like your, – Shirsh Shukla Dec 23 '20 at 14:02
0

This is how you combine streams with bloc using RxDart, you have emit new values if there is something new in listener, that's all. You might create listener whenever you want to do calls to your backend.

import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:rxdart/rxdart.dart';

class TestState {
  final bool isValid;

  TestState(this.isValid);
}

class TestCubit extends Cubit<TestState> {
  final List<StreamSubscription> _ss = [];
  final _emailSubject = BehaviorSubject<String>.seeded(null);
  final _passwordSubject = BehaviorSubject<String>.seeded(null);

  TestCubit() : super(TestState(false)) {
    _ss.add(_subscribeToEmailAndPassword());
  }

  StreamSubscription _subscribeToEmailAndPassword() {
    return Rx.combineLatest([_emailSubject, _passwordSubject], (list) {
      if (list[0] != null && list[1] != null) {
        return true;
      }
      return false;
    }).listen((value) {
      emit(TestState(value));
    });
  }

  @override
  Future<void> close() async {
    _ss.forEach((e) async => await e.cancel());
    await super.close();
  }

  void emailFieldChange(String email) {
    _emailSubject.add(email);
  }

  void passwordFieldChange(String password) {
    _passwordSubject.add(password);
  }
}
Rafal
  • 85
  • 2
  • 14
  • Like in the other answer, I was able to solve this problem using RxDart. The question I'm asking is how to do this WITHOUT using RxDart. I want to use the "bloc" package or more specifically, the "flutter_bloc" package. I'm trying to determine if I can use flutter_bloc instead of RxDart. – JustLearningAgain Dec 27 '20 at 04:21